<div id="large-input-82371-13733" class="large-input has-overlay-link">
<label for="large-input-82371-13733-input" class="large-input__label">Suchbegriff</label>
<input class="large-input__input" id="large-input-82371-13733-input" name="search" type="text">
</div>
{% set id = id ??? html_id('large-input') -%}
<div {{ html_attributes({
id: id ?? false,
class: {
'large-input': true,
'large-input--frameless': frameless ?? false,
'has-overlay-link': true,
},
}, attrs ?? {}) }}>
<label for="{{ 'input' | namespaceInputId(id) }}" class="large-input__label">
{{- label -}}
</label>
<input {{ html_attributes({
class: 'large-input__input',
id: 'input' | namespaceInputId(id),
name: name,
type: type ??? 'text',
required: required ?? false,
value: value ?? null,
'data-autocomplete': autocomplete ?? false,
autocomplete: autocomplete|default ? 'off',
}, inputAttrs ?? {}) }}>
</div>
{
"name": "search",
"label": "Suchbegriff"
}
:root {
--large-input-background-color: var(--color-white);
--large-input-border-color: var(--color-midnight);
--large-input-border-width: 2px;
--large-input-color: var(--color-midnight);
--large-input-font-size: 2.4rem;
--large-input-height: 8.4rem;
--large-input-label-color: var(--color-grey-dark);
--large-input-label-font-size: 0.55em;
--large-input-padding-block: 1.6rem;
--large-input-padding-inline: 2.4rem;
--large-input-cancel-button-size: 1.8rem;
--large-input-highlight-color: var(--color-orange);
}
.large-input {
background-color: var(--large-input-background-color);
box-shadow: inset 0 0 0 var(--large-input-border-width) var(--large-input-border-color);
color: var(--large-input-color);
font-size: var(--large-input-font-size);
position: relative;
user-select: none;
}
.large-input--frameless {
--large-input-border-width: 0;
}
.large-input__label {
color: var(--large-input-label-color);
display: block;
font-size: var(--large-input-label-font-size);
inset-block-start: var(--large-input-padding-block);
inset-inline-start: var(--large-input-padding-inline);
padding-inline: 0;
position: absolute;
}
.large-input__input {
--focus-outline-offset: 0;
--selection-background-color: var(--large-input-color);
--selection-foreground-color: var(--large-input-background-color);
background-color: transparent;
block-size: var(--large-input-height);
display: block;
font-size: inherit;
font-weight: var(--font-weight-bold);
inline-size: 100%;
padding-block-end: var(--large-input-padding-block);
padding-block-start: calc(var(--large-input-padding-block) + var(--large-input-label-font-size) + 1rem);
padding-inline: var(--large-input-padding-inline);
.large-input--frameless & {
--focus-outline-offset: 3px;
}
&::-webkit-search-cancel-button {
display: none;
}
}
.large-input__autocomplete {
animation: opacity var(--duration-default);
background-color: var(--large-input-background-color);
border: var(--large-input-border-width) solid var(--large-input-border-color);
border-block-start: 0;
display: grid;
font-size: var(--large-input-font-size);
gap: 2rem;
padding-block-end: calc(var(--large-input-padding-block) * 2);
padding-block-start: var(--large-input-padding-block);
padding-inline: var(--large-input-padding-inline);
transform: translateY(-1rem);
z-index: z-index('dropdown');
&[hidden] {
display: none;
}
}
.large-input__autocomplete-option {
--large-input-highlight-opacity: 0;
position: relative;
&:is([aria-selected='true']) {
--large-input-highlight-opacity: 1;
}
&::before {
background-color: var(--large-input-highlight-color);
border-block: 0.25em solid var(--large-input-highlight-color);
border-inline: var(--large-input-padding-inline) solid var(--large-input-highlight-color);
content: '';
inset-block: -0.25em;
inset-inline: calc(var(--large-input-padding-inline) * -1);
opacity: var(--large-input-highlight-opacity);
pointer-events: none;
position: absolute;
transition-duration: 0.2s;
transition-property: opacity;
z-index: -1;
}
}
.large-input__autocomplete-option--empty {
color: var(--color-grey-dark);
}
import autocomplete, { type AutocompleteItem } from 'autocompleter';
type AutocompleteApiItem = {
title: string;
};
document
.querySelectorAll<HTMLInputElement>('input[data-autocomplete]')
.forEach(($input) => {
autocomplete<AutocompleteApiItem & AutocompleteItem>({
className: 'large-input__autocomplete',
disableAutoSelect: true,
input: $input,
minLength: 3,
emptyMsg: 'Keine Ergebnisse gefunden',
preventSubmit: 1,
render(item) {
const $item = document.createElement('div');
$item.textContent = item.title;
return $item;
},
async fetch(text, update) {
// nosemgrep: nodejs_scan.javascript-ssrf-rule-node_ssrf
const results = await fetch(`${$input.dataset.autocomplete}${text}`, {
method: 'GET',
credentials: 'include',
headers: {
Accept: 'application/json',
},
});
const items: AutocompleteApiItem[] = await results.json();
update(items.slice(0, 5));
},
onSelect(item) {
$input.value = item.title;
},
customize(_, __, $container) {
$container.classList.remove('autocomplete');
$container.querySelectorAll('[role="option"]').forEach(($option) => {
$option.classList.remove('selected');
$option.classList.add('large-input__autocomplete-option');
});
$container.querySelectorAll('.empty').forEach(($empty) => {
$empty.classList.remove('empty');
$empty.classList.add('large-input__autocomplete-option');
$empty.classList.add('large-input__autocomplete-option--empty');
});
},
});
});
No notes defined.