Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIF-2291 - Cleanups in searchbar component #655

Merged
merged 15 commits into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui.apps/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ module.exports = function(config) {
'node_modules/@babel/polyfill/dist/polyfill.js',
'src/main/content/jcr_root/apps/core/cif/components/commerce/product/**/js/*.js',
'src/main/content/jcr_root/apps/core/cif/components/commerce/carousel/**/js/carousel.js',
'src/main/content/jcr_root/apps/core/cif/components/commerce/searchbar/v2/**/js/searchbar.js',
'src/main/content/jcr_root/apps/core/cif/components/structure/navigation/**/js/*.js',
'src/main/content/jcr_root/apps/core/cif/components/content/teaser/**/js/*.js',

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:description="Searchbar component that displays input field for product search"
jcr:primaryType="cq:Component"
jcr:title="Searchbar"
cq:icon="search"
sling:resourceSuperType="core/cif/components/commerce/searchbar/v1/searchbar"
componentGroup=".hidden" />
componentGroup=".hidden" />
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ limitations under the License.

Searchbar component is a server-side component written in HTL, displaying a search input. After submitting the components redirects to the search results page defined by the `cq:cifSearchResultsPage` property and passing the search term as a query parameter.

The visibility of the component can be toggled using any DOM element with the `searchTrigger__root` CSS class assigned.
The visibility of the component can be toggled using any DOM element with the `searchbar__trigger` CSS class assigned.

## Features

Expand All @@ -34,18 +34,20 @@ This component uses the `com.adobe.cq.commerce.core.components.models.searchbar.

```
BLOCK searchbar
ELEMENT searchBar__root
searchBar__searchInner
searchBar__form
textInput__input
field__input
message__root
searchBar__SearchAutocompleteWrapper
fieldIcons__root
fieldIcons__input
fieldIcons__before
fieldIcons__after
icon__root
ELEMENT searchbar__root
ELEMENT searchbar__trigger
ELEMENT searchbar__trigger-icon
ELEMENT searchbar__body
ELEMENT searchbar__body--open
ELEMENT searchbar__form-container
ELEMENT searchbar__form
ELEMENT searchbar__fields
ELEMENT searchbar__input-container
ELEMENT searchbar__input
ELEMENT searchbar__input-before
ELEMENT searchbar__input-after
ELEMENT searchbar__reset-button
ELEMENT searchbar__search-icon
```

## Information
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Search Bar"
sling:resourceType="cq/gui/components/authoring/dialog"
trackingFeature="cif-core-components:searchbar:v2">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<column jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<placeholder jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Placeholder text for the search field."
fieldLabel="Placeholder Text"
name="./placeholder"/>
<id jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="HTML ID attribute to apply to the component."
fieldLabel="ID"
name="./id"/>
</items>
</column>
</items>
</content>
</jcr:root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="[core.cif.components.searchbar.v2]"
dependencies="[core.cif.components.theme]"
jsProcessor="[default:none,min:none]"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#base=css

searchbar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Copyright 2021 Adobe
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
.searchbar__trigger {
display: none;
}

.searchbar__form {
display: grid;
}

.searchbar__input-before,
.searchbar__input-after {
display: flex;
align-items: center;
justify-content: center;
width: 2.25rem;
}

.searchbar__input-before {
grid-area: before;
}

.searchbar__input-after {
grid-area: after;
justify-self: end;
}

.searchbar__fields {
display: inline-grid;
grid-template-areas: 'before input after';
}

.searchbar__search-icon {
align-items: center;
display: inline-flex;
justify-content: center;
height: 25px;
width: 25px;
}

.searchbar__input-container {
grid-column: before-start / after-end;
grid-row: input-start / input-end;
}

.searchbar__input {
padding-left: calc(1.875rem * var(--iconsBefore) - -0.375rem - 1px);
padding-right: calc(1.875rem * var(--iconsAfter) - -2.1rem - 1px);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Copyright 2021 Adobe
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
'use strict';

class Searchbar {
constructor(props) {
this._classes = {
open: 'searchbar__body--open'
};

this._searchBarRoot = document.querySelector(Searchbar.selectors.searchBarRoot);
if (!this._searchBarRoot) {
return;
}

this._searchBox = this._searchBarRoot.querySelector(Searchbar.selectors.searchBox);

let stateObject = {};
if (props && props.params) {
stateObject.visible = !!props.params.query;
stateObject.query = props.params.query;
}

this._state = stateObject;

if (stateObject.visible) {
this._show();
this._searchBox.value = stateObject.query;
this._showResetButton();
}

this._installListeners();
}

_getOrCreateResetButton() {
if (!this._resetButtonElement) {
const html = new DOMParser().parseFromString(Searchbar.CLEAR_BUTTON_HTML, 'text/html');
this._resetButtonElement = html.body.firstChild;
}
return this._resetButtonElement;
}

_installListeners() {
let that = this;
// listen to onclick on the "search" icon in the header
document.querySelector(Searchbar.selectors.searchBarToggle).addEventListener('click', event => {
this.toggle();
});
}

toggle() {
if (this._state.visible) {
this._hide();
} else {
this._show();
}

this._state.visible = !this._state.visible;
}

_showResetButton() {
const afterField = this._searchBarRoot.querySelector(Searchbar.selectors.afterField);
afterField.appendChild(this._getOrCreateResetButton());

this._searchBarRoot.querySelector(Searchbar.selectors.resetButton).addEventListener('click', e => {
//clear the search field
this._searchBox.value = '';

//remove the reset button
afterField.removeChild(afterField.childNodes[0]);

//re-register the listener on the searchbox
this._registerSearchBoxListener();
this._searchBox.focus();
});
}

_registerSearchBoxListener() {
const _handleKeyDown = e => {
const input = e.currentTarget;
this._showResetButton();
this._searchBox.removeEventListener('keydown', _handleKeyDown);
};
this._searchBox.addEventListener('keydown', _handleKeyDown);
}

_show() {
this._searchBarRoot.classList.add(this._classes.open);
this._searchBox.focus();
this._registerSearchBoxListener();
}

_hide() {
this._searchBarRoot.classList.remove(this._classes.open);
}
}

Searchbar.selectors = {
searchBarRoot: "div[role='search']",
searchBox: "input[role='searchbox']",
afterField: '.searchbar__input-after',
resetButton: '.searchbar__reset-button',
searchBarToggle: '.searchbar__trigger'
};

Searchbar.CLEAR_BUTTON_HTML = `
<button class="searchbar__reset-button" type="button">
<span class="icon__root">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</span>
</button>`;

(function() {
function onDocumentReady() {
const queryParams = new URLSearchParams(location.search);
if (queryParams.has('search_query')) {
const searchBar = new Searchbar({ params: { query: queryParams.get('search_query') } });
} else {
const searchBar = new Searchbar({});
}
}

if (document.readyState !== 'loading') {
onDocumentReady();
} else {
document.addEventListener('DOMContentLoaded', onDocumentReady);
}
})();

export default Searchbar;
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
<sly data-sly-use.searchbar="${'com.adobe.cq.commerce.core.components.models.searchbar.Searchbar'}"/>

<div class="searchbar__root" id="${searchbar.id}" data-cmp-data-layer="${searchbar.data.json}">
<button class="searchTrigger__root clickable__root">
<span class="icon-root">
<button class="searchbar__trigger" title="${properties.placeholder || 'Search' @ i18n}">
<span class="searchbar__trigger-icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
Expand All @@ -24,16 +24,16 @@
</svg>
</span>
</button>
<div class="searchBar__root" role="search">
<div class="searchBar__searchInner">
<form class="searchBar__form" autocomplete="off" _lpchecked="1" action="${searchbar.searchResultsPageUrl}">
<span class="fieldIcons__root" style="--iconsBefore:1; --iconsAfter:0;">
<span class="fieldIcons__input">
<input class="textInput__input field__input" name="search_query" value="" role="searchbox"
<div class="searchbar__body" role="search">
<div class="searchbar__form-container">
<form class="searchbar__form" autocomplete="off" _lpchecked="1" action="${searchbar.searchResultsPageUrl}">
<span class="searchbar__fields" style="--iconsBefore:1; --iconsAfter:0;">
<span class="searchbar__input-container">
<input class="searchbar__input" name="search_query" value="" role="searchbox"
placeholder="${properties.placeholder || 'Search' @ i18n}">
</span>
<span class="fieldIcons__before">
<span class="icon__root">
<span class="searchbar__input-before">
<span class="searchbar__search-icon">
<svg
xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round"
Expand All @@ -43,10 +43,8 @@
</svg>
</span>
</span>
<span class="fieldIcons__after"></span>
<span class="searchbar__input-after"></span>
</span>
<p class="message__root"></p>
<div class="searchBar__SearchAutocompleteWrapper"></div>
</form>
</div>
</div>
Expand Down
Loading