<div class="a-search a-search--inverted a-search--expanded">
<form role="search" method="get" id="searchform" class="a-search__form" action="" autocomplete="off">
<div>
<label class="screen-reader-text" for="s">Suche</label>
<input class="a-search__field" type="text" value="" name="s" id="s" placeholder="Suche">
<label class="a-search__submit-label">
<input class="a-search__submit" type="submit" id="searchsubmit" value="">
<svg class="a-search__icon" aria-hidden="true">
<title></title>
<use xlink:href="#glass"></use>
</svg>
</label>
</div>
</form>
</div>
<div class="a-search {{modifiers_classes}}">
<form role="search" method="get" id="searchform" class="a-search__form" action="{{action}}" autocomplete="off">
<div>
<label class="screen-reader-text" for="s">{{ search }}</label>
<input class="a-search__field" type="text" value="{{ terms }}" name="s" id="s" placeholder="{{ search }}">
<label class="a-search__submit-label">
<input class="a-search__submit" type="submit" id="searchsubmit" value="{{ search_submit }}">
<svg class="a-search__icon" aria-hidden="true">
<title>{{ search_submit }}</title>
<use xlink:href="#glass"></use>
</svg>
</label>
</div>
</form>
</div>
.a-search {
$offset: 0.75em;
position: relative;
&:not(&--inverted) {
margin-left: #{- $offset};
@include media($_DESKTOP) {
margin-left: 0;
}
}
@include media($_DESKTOP) {
padding-top: 0.533em;
}
&--covering {
@include media($_DESKTOP) {
position: absolute;
background: rgba(255, 255, 255, 0);
height: 60px;
transition: all $transition-ease $transition-mid;
width: 100%;
max-width: 34px; // this will be overwritten by js
&.is-active {
background: $color-white;
}
}
}
&--expanded {
width: 100%;
max-width: 100%;
}
&__icon {
fill: none;
stroke: $color-text;
width: 1.333em;
height: 1.333em;
margin-bottom: -0.25em;
margin-left: -2em;
cursor: pointer;
transition: stroke $transition-ease $transition-fast;
&.highlight,
&:hover,
&:focus {
stroke: $color-secondary;
}
}
&--expanded &__icon {
margin-left: 0;
}
&__field {
background: transparent;
border: none;
width: 8.8em;
max-width: 300px;
font-size: 0.9375rem;
font-weight: 700;
color: $color-text;
transition: all $transition-ease $transition-mid;
height: 2.625em;
padding-left: $offset;
border-bottom: 2px solid transparent;
@include media($_DESKTOP) {
width: 2em;
color: transparent;
}
&::placeholder {
color: $color-text;
transition: color $transition-ease $transition-fast;
@include high-contrast {
color: $color-text;
}
}
&:focus,
&.is-active {
width: 100%;
background-color: $color-grey-1;
border-bottom-color: $color-grey-2;
outline: none;
color: $color-text;
padding-right: 2.4em;
@include high-contrast {
border-color: $color-text;
}
&::placeholder {
color: $color-grey-2;
@include high-contrast {
color: $color-text;
}
}
}
&:not(:focus),
&:not(.is-active) {
cursor: pointer;
@include media($_MOBILE) {
&.highlight {
&::placeholder {
color: $color-secondary;
}
}
}
@include media($_DESKTOP) {
&::placeholder {
color: transparent;
}
}
}
}
&--inverted &__field {
background-color: $color-white;
}
&--expanded &__field {
width: 100%;
max-width: 100%;
color: $color-text;
border-bottom-color: $color-grey-3;
cursor: text;
padding-right: 2.4em;
@include high-contrast {
border-color: $color-text;
}
&::placeholder {
color: $color-grey-3;
@include high-contrast {
color: $color-text;
}
}
}
&__submit-label {
width: 0;
position: absolute;
top: 7px;
@include media($_DESKTOP) {
top: 16px;
}
}
&--expanded &__submit-label {
right: 39px;
}
&__submit {
// hide for none screen readers
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
}
import BaseView from 'base-view';
import browserSupportsClassList from './../../../js/utils/classList';
const ICON_SELECTOR = '.a-search__icon';
const FIELD_SELECTOR = '.a-search__field';
const SUBMIT_LABEL_SELECTOR = '.a-search__submit-label';
const COVERING_CLASS = 'a-search--covering';
const ACTIVE_STATE = 'is-active';
const HOVER_STATE = 'highlight';
export default class ASearch extends BaseView {
initialize() {
this.icon = this.getScopedElement(ICON_SELECTOR);
this.field = this.getScopedElement(FIELD_SELECTOR);
this.overIcon = false;
this.overField = false;
this.active = false;
this.covering = this.element.classList.contains(COVERING_CLASS);
if (this.covering) {
this.initialWidth = this.element.scrollWidth;
}
}
bind() {
super.bind();
this.on('mouseover', ICON_SELECTOR, (event) => this.setHover(event));
this.on('mouseover', FIELD_SELECTOR, (event) => this.setHover(event));
this.on('mouseout', ICON_SELECTOR, (event) => this.setHover(event));
this.on('mouseout', FIELD_SELECTOR, (event) => this.setHover(event));
this.on('click', SUBMIT_LABEL_SELECTOR, (event) => this.handleGlassClick(event));
this.on('focus', FIELD_SELECTOR, () => this.setFocus(true));
this.on('blur', FIELD_SELECTOR, () => this.setFocus(false));
}
setHover(event) {
let overState = 'mouseover' === event.type;
this.setOverState(event.target, overState);
let hoverState = (!this.active && (this.overIcon || this.overField));
this.setHoverState(hoverState);
}
setHoverState(active) {
if (active) {
if (browserSupportsClassList(this.icon)) {
this.addClass(this.icon, HOVER_STATE);
}
this.addClass(this.field, HOVER_STATE);
} else {
if (browserSupportsClassList(this.icon)) {
this.removeClass(this.icon, HOVER_STATE);
}
this.removeClass(this.field, HOVER_STATE);
}
}
handleGlassClick(event) {
if (!this.active) {
event.preventDefault();
this.setFocus(true);
} else if (!this.field.value) {
event.preventDefault();
this.setFocus(false);
}
}
setFocus(active) {
if (active) {
this.open();
} else {
setTimeout(() => {
// without delay we can't click the icon
// this allows us send the form by click
this.close();
}, 200);
}
}
open() {
this.active = true;
this.field.focus();
this.setHoverState(false);
this.addClass(this.field, ACTIVE_STATE);
// expand the whole element to make sure we hide all elements on the right
if (this.covering) {
let left = this.element.offsetLeft;
let vw = document.body.clientWidth;
this.element.style.maxWidth = (vw - left) + 'px';
this.addClass(ACTIVE_STATE);
}
}
close() {
this.removeClass(this.field, ACTIVE_STATE);
this.active = false;
// shrink the background
if (this.covering) {
this.element.style.maxWidth = null;
this.removeClass(ACTIVE_STATE);
}
}
setOverState(target, state) {
if ('text' === target.type) {
this.overField = state;
} else {
this.overIcon = state;
}
}
}
{
"aria-label-search": "Suche",
"search": "Suche",
"modifiers": [
"inverted",
"expanded"
]
}
No notes defined.