Skip to content

Commit

Permalink
Render search bars in device list page
Browse files Browse the repository at this point in the history
  • Loading branch information
pkong-ds committed May 30, 2024
1 parent 5b5c04c commit 2bcfad4
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 163 deletions.
125 changes: 76 additions & 49 deletions public/scripts/device.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const isDebug = true;
const isDebug = false;
const NUM_DEFAULT_MODEL_ITEMS_TO_DISPLAY = 0;
const NUM_DEFAULT_BRAND_ITEMS_TO_DISPLAY = 0;

function ready(fn) {
if (document.readyState != "loading") {
Expand All @@ -14,15 +16,19 @@ class RootViewModel {
selectedBrand = "all";
_deviceList;
_brandDeviceList;
_modelItems;
_brandItems;

constructor(deviceList, brandDeviceList) {
constructor(deviceList, brandDeviceList, modelItems, brandItems) {
mobx.makeObservable(this, {
searchText: mobx.observable,
selectedBrand: mobx.observable,
shouldShowSearchClear: mobx.computed,
});
this._deviceList = deviceList;
this._brandDeviceList = brandDeviceList;
this._modelItems = modelItems;
this._brandItems = brandItems;
}

get shouldShowSearchClear() {
Expand Down Expand Up @@ -95,67 +101,81 @@ function handleSelectBrandOption(selectParent, viewModel) {

function handleSearchInput(viewModel) {
// both inputs: header for lg-screen & top-of-page for sm-screen
const searchInputList = document.querySelectorAll(
".device-list__search-input",
);
const searchInputList = document.querySelectorAll(".aa-Input");
searchInputList.forEach((searchInput) => {
searchInput.addEventListener("input", (e) => {
viewModel.searchText = e.target.value;
});
});

// both inputs: header for lg-screen & top-of-page for sm-screen
const searchContainerList = document.querySelectorAll(
".device-list__search-container",
);
searchContainerList.forEach((searchContainer, i) => {
searchContainer.addEventListener("click", () => {
searchInputList[i].focus();
});
});
}

function handleSearchClearBtn(viewModel) {
const searchInputList = document.querySelectorAll(
".device-list__search-input",
);
const searchClearBtnList = document.querySelectorAll(
".device-list__search-input__clear-btn",
);

searchClearBtnList.forEach((searchClearBtn) => {
searchClearBtn.addEventListener("click", () => {
viewModel.searchText = "";
});
function initializeSearch(viewModel, containerId) {
console.log(containerId);
const { autocomplete } = window["@algolia/autocomplete-js"];
autocomplete({
container: containerId,
placeholder: "Search Device",
getSources() {
return [
{
sourceId: "models",
getItems({ query }) {
const defaultDisplayItems = modelItems.slice(
0,
NUM_DEFAULT_MODEL_ITEMS_TO_DISPLAY,
);
const filtered = modelItems.filter((model) => {
return model.name.toLowerCase().includes(query.toLowerCase());
});
return filtered.length > 0 ? filtered : defaultDisplayItems;
},
templates: {
item({ item, html }) {
return html`<a class="aa-ItemWrapper" href="${item.pathname}"
>${item.name}</a
>`;
},
},
getItemUrl({ item }) {
return `${window.location.origin}${item.pathname}`;
},
},
{
sourceId: "brands",
getItems({ query }) {
const defaultDisplayItems = brandItems.slice(
0,
NUM_DEFAULT_BRAND_ITEMS_TO_DISPLAY,
);
const filtered = brandItems.filter((brand) => {
return brand.name.toLowerCase().includes(query.toLowerCase());
});
return filtered.length > 0 ? filtered : defaultDisplayItems;
},
templates: {
item({ item, components, html }) {
return html`<a class="aa-ItemWrapper" href="${item.pathname}"
>${item.name}</a
>`;
},
},
getItemUrl({ item }) {
return `${window.location.origin}${item.pathname}`;
},
},
];
},
});

mobx.reaction(
() => viewModel.searchText,
() => {
searchInputList.forEach((searchInput) => {
searchInput.value = viewModel.searchText;
});
searchClearBtnList.forEach((searchClearBtn) => {
if (viewModel.shouldShowSearchClear) {
searchClearBtn.classList.remove("d-none");
} else {
searchClearBtn.classList.add("d-none");
}
});
},
);
handleSearchInput(viewModel);

tippy("[data-tippy-content]", {
tippy(".aa-ClearButton", {
content: "Clear",
placement: "bottom",
theme: "light-border",
});
}

function handleSearch(viewModel) {
handleSearchInput(viewModel);
handleSearchClearBtn(viewModel);
}

function main() {
const deviceGrids = document.querySelectorAll(".device-grid");
const brands = document.querySelectorAll(".device-brand-list__item-button");
Expand All @@ -164,12 +184,19 @@ function main() {
const viewModel = new RootViewModel(
window.deviceList,
window.brandDeviceList,
window.modelItems,
window.brandItems,
);
if (isDebug) {
window.viewModel = viewModel;
}

handleSearch(viewModel);
[
"#device-list__header__autocomplete",
"#device-list__page__autocomplete",
].forEach((containerId) => {
initializeSearch(viewModel, containerId);
});

mobx.reaction(
() => viewModel.selectedBrand,
Expand Down
6 changes: 1 addition & 5 deletions public/scripts/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ function initializeAutocomplete(viewModel) {
});
}
function main() {
const viewModel = new RootViewModel(
window.modelItems,
window.brandItems,
window.brandThumbnailList,
);
const viewModel = new RootViewModel(window.modelItems, window.brandItems);
initializeAutocomplete(viewModel);
}
20 changes: 2 additions & 18 deletions src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -138,25 +138,9 @@ const { shouldRenderSearchBar } = Astro.props;
{
!!shouldRenderSearchBar ? (
<div class="header__search-container">
<div class="header__search-device__container device-list__search-container">
<img src="/Images/search.svg" />
<input
class="header__search-device__input device-list__search-input"
placeholder="Search Device"
type="search"
/>
<button
class="header__search-device__clear-btn d-none device-list__search-input__clear-btn"
data-tippy-content="Clear"
>
<img src="/Images/cross-gray.svg" />
</button>
</div>
{/* Add suggestion list here */}
<div id="device-list__header__autocomplete" />
</div>
) : (
<div class="header__search-container"> </div>
)
) : undefined
}

<div class="header__share">
Expand Down
24 changes: 9 additions & 15 deletions src/pages/type/[type].astro
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import "/src/styles/device.css";
import { DEVICE_MANAGER } from "../../scripts/deviceManager";
import type { BrandValue, ModelThumbnail } from "../../scripts/model";
import { BrandEnum, DeviceTypeEnum } from "../../scripts/parse";
import { getModelItems, getBrandItems } from "../../scripts/algolia/generate";
const modelItems = getModelItems(DEVICE_MANAGER);
const brandItems = getBrandItems(DEVICE_MANAGER);
export async function getStaticPaths() {
const devicePaths = DeviceTypeEnum.options.map((deviceType) => ({
Expand Down Expand Up @@ -42,25 +45,16 @@ const brandList: Array<BrandEnum | "all"> = ["all", ...nonEmptyBrands];
content="MockUPhone supports devices including iPhone mockup, iPad mockup, Android mockup and TV mockup. You can check out the whole device list via this page."
/>
<script type="text/javascript" src="/scripts/device.js"></script>
<script define:vars={{ thumbnailList, brandThumbnailList }}>
<script
define:vars={{ thumbnailList, brandThumbnailList, modelItems, brandItems }}
>
window.thumbnailList = thumbnailList;
window.brandThumbnailList = brandThumbnailList;
window.modelItems = modelItems;
window.brandItems = brandItems;
</script>
<section class="search-device">
<div class="search-device__container device-list__search-container">
<img src="/Images/search.svg" />
<input
class="search-device__input device-list__search-input"
placeholder="Search Device"
type="search"
/>
<button
class="search-device__clear-btn d-none device-list__search-input__clear-btn"
data-tippy-content="Clear"
>
<img src="/Images/cross-gray.svg" />
</button>
</div>
<div id="device-list__page__autocomplete"></div>
{/* Add suggestion list here */}
</section>
<section class="device-type">
Expand Down
83 changes: 7 additions & 76 deletions src/styles/device.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import url("./search.css");

.header__search-container {
display: none;
}
Expand All @@ -14,62 +16,27 @@
}
}

.header__search-device__container {
#device-list__header__autocomplete {
max-width: 38%; /* 543 / 1440 */
flex: 1 1 0%;

margin: 0;
padding: 16px 20px;
display: flex;
height: 56px;
background: var(--white);
border: 1px solid var(--gray-5);
box-sizing: border-box;
border-radius: 9px;
column-gap: 12px;
}

@media (min-width: 992px) {
.header__search-device__container {
margin: 0 0 0 136px; /* to prevent search bar overlapping with mockuphone logo */
#device-list__header__autocomplete {
margin: 0 0 0 144px; /* to prevent search bar overlapping with mockuphone logo */
}
}

@media (min-width: 1300px) {
.header__search-device__container {
#device-list__header__autocomplete {
margin: 0;
}
}

.header__search-device__input {
flex: 1 1 0%;
border: none;
outline: none;
font-size: 18px;
max-width: 90%;
min-width: 0;
}

.header__search-device__input::placeholder {
color: var(--gray-3);
font-size: 14px;
}

.header__search-device__clear-btn {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
flex: none;
background-color: white;
padding: 12px;
margin: -12px;
}

.header__search-device__clear-btn:focus {
outline: none;
}

.search-device {
display: flex;
padding: 40px 20px 0 20px;
Expand All @@ -81,48 +48,12 @@
}
}

.search-device__container {
#device-list__page__autocomplete {
flex: 1 1 0%;
/* justify-content: space-between; */

margin: 0;
padding: 16px 20px;
display: flex;
height: 56px;
background: var(--white);
border: 1px solid var(--gray-5);
box-sizing: border-box;
border-radius: 9px;
column-gap: 12px;
}

.search-device__input {
flex: 1 1 0%;
border: none;
outline: none;
font-size: 18px;
max-width: 90%;
min-width: 0;
}

.search-device__input::placeholder {
color: var(--gray-3);
font-size: 14px;
}

.search-device__clear-btn {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
flex: none;
background-color: white;
padding: 12px;
margin: -12px -36px -12px -12px;
}

.search-device__clear-btn:focus {
outline: none;
}

.device-type {
Expand Down
3 changes: 3 additions & 0 deletions src/styles/search.css
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
.aa-ItemWrapper {
height: 100%;
}
.aa-Panel {
z-index: 100;
}

/* Mobile */

Expand Down

0 comments on commit 2bcfad4

Please sign in to comment.