@getlupa/client 0.6.0-alpha-19 → 0.6.0-alpha-22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/cjs/components/product-list/CategoryDescription.vue.d.ts +0 -1
  2. package/dist/cjs/components/search-results/filters/MobileFilterSidebar.vue.d.ts +1 -1
  3. package/dist/cjs/components/search-results/products/SearchResultsMobileToggle.vue.d.ts +1 -1
  4. package/dist/cjs/components/search-results/products/SearchResultsProducts.vue.d.ts +8 -0
  5. package/dist/cjs/constants/development/searchResultsDev.example.const.d.ts +2 -0
  6. package/dist/cjs/constants/global.const.d.ts +1 -0
  7. package/dist/cjs/index.min.js +84 -22
  8. package/dist/cjs/store/modules/searchResult.d.ts +6 -0
  9. package/dist/cjs/types/search-results/SearchResultsOptions.d.ts +3 -0
  10. package/dist/cjs/utils/scroll.utils.d.ts +2 -0
  11. package/dist/es/components/product-list/CategoryDescription.vue.d.ts +0 -1
  12. package/dist/es/components/search-results/filters/MobileFilterSidebar.vue.d.ts +1 -1
  13. package/dist/es/components/search-results/products/SearchResultsMobileToggle.vue.d.ts +1 -1
  14. package/dist/es/components/search-results/products/SearchResultsProducts.vue.d.ts +8 -0
  15. package/dist/es/constants/development/searchResultsDev.example.const.d.ts +2 -0
  16. package/dist/es/constants/global.const.d.ts +1 -0
  17. package/dist/es/index.min.js +84 -22
  18. package/dist/es/store/modules/searchResult.d.ts +6 -0
  19. package/dist/es/types/search-results/SearchResultsOptions.d.ts +3 -0
  20. package/dist/es/utils/scroll.utils.d.ts +2 -0
  21. package/dist/iife/components/product-list/CategoryDescription.vue.d.ts +0 -1
  22. package/dist/iife/components/search-results/filters/MobileFilterSidebar.vue.d.ts +1 -1
  23. package/dist/iife/components/search-results/products/SearchResultsMobileToggle.vue.d.ts +1 -1
  24. package/dist/iife/components/search-results/products/SearchResultsProducts.vue.d.ts +8 -0
  25. package/dist/iife/constants/development/searchResultsDev.example.const.d.ts +2 -0
  26. package/dist/iife/constants/global.const.d.ts +1 -0
  27. package/dist/iife/index.min.js +1 -1
  28. package/dist/iife/store/modules/searchResult.d.ts +6 -0
  29. package/dist/iife/types/search-results/SearchResultsOptions.d.ts +3 -0
  30. package/dist/iife/utils/scroll.utils.d.ts +2 -0
  31. package/dist/style.css +1 -1
  32. package/package.json +1 -1
@@ -2,7 +2,6 @@ import Vue from "vue";
2
2
  import { ProductListOptions } from "@/types/product-list/ProductListOptions";
3
3
  export default class CategoryDescription extends Vue {
4
4
  options: ProductListOptions;
5
- get title(): string | undefined;
6
5
  get description(): string | undefined;
7
6
  get overviewVisible(): boolean;
8
7
  }
@@ -2,7 +2,7 @@ import { SearchResultsFilterOptions } from "@/types/search-results/SearchResults
2
2
  import Vue from "vue";
3
3
  export default class MobileFilterSidebar extends Vue {
4
4
  options: SearchResultsFilterOptions;
5
- setSidebarVisibility: ({ visible, }: {
5
+ setSidebarState: ({ visible, }: {
6
6
  visible: boolean;
7
7
  }) => void;
8
8
  isMobileSidebarVisible: boolean;
@@ -3,7 +3,7 @@ export default class SearchResultsMobileToggle extends Vue {
3
3
  label: string;
4
4
  showFilterCount: boolean;
5
5
  currentFilterCount: number;
6
- setSidebarVisibility: ({ visible, }: {
6
+ setSidebarState: ({ visible, }: {
7
7
  visible: boolean;
8
8
  }) => void;
9
9
  handleMobileToggle(): void;
@@ -8,6 +8,7 @@ export default class SearchResultsProducts extends Vue {
8
8
  loading: boolean;
9
9
  hasResults: boolean;
10
10
  currentQueryText: string;
11
+ isPageEmpty: boolean;
11
12
  isMobileSidebarVisible: boolean;
12
13
  productCardOptions(): SearchResultsProductCardOptions;
13
14
  get similarQueriesLabels(): SearchResultsSimilarQueriesLabels;
@@ -21,4 +22,11 @@ export default class SearchResultsProducts extends Vue {
21
22
  page: number;
22
23
  get columnSize(): string;
23
24
  getProductKey(index: string, product: Document): string;
25
+ appendParams: ({ params, }: {
26
+ params: {
27
+ name: string;
28
+ value: string;
29
+ }[];
30
+ }) => void;
31
+ goToFirstPage(): void;
24
32
  }
@@ -13,6 +13,8 @@ export declare const SEARCH_RESULTS_CONFIGURATION: {
13
13
  priceSeparator: string;
14
14
  showMore: string;
15
15
  emptyResults: string;
16
+ noItemsInPage: string;
17
+ backToFirstPage: string;
16
18
  mobileFilterButton: string;
17
19
  htmlTitleTemplate: string;
18
20
  noResultsSuggestion: string;
@@ -11,4 +11,5 @@ export declare const XL_MIN_WIDTH = 1199;
11
11
  export declare const MAX_FACET_VALUES = 5000;
12
12
  export declare const CURRENCY_KEY_INDICATOR = "price";
13
13
  export declare const DEFAULT_PAGE_SIZE = 12;
14
+ export declare const DEFAULT_PAGE_SIZE_SELECTION: number[];
14
15
  export declare const LUPA_ROUTING_EVENT = "lupaRedirect";
@@ -11919,6 +11919,7 @@ const XL_MIN_WIDTH = 1199;
11919
11919
  const MAX_FACET_VALUES = 5000;
11920
11920
  const CURRENCY_KEY_INDICATOR = "price";
11921
11921
  const DEFAULT_PAGE_SIZE = 12;
11922
+ const DEFAULT_PAGE_SIZE_SELECTION = [12, 24, 36, 60];
11922
11923
  const LUPA_ROUTING_EVENT = "lupaRedirect";
11923
11924
 
11924
11925
  const formatRange = (filter) => {
@@ -15407,8 +15408,9 @@ __vue_render__$J._withStripped = true;
15407
15408
  const searchResult$h = namespace("searchResult");
15408
15409
  let FacetDisplay = class FacetDisplay extends Vue$1 {
15409
15410
  constructor() {
15411
+ var _a, _b;
15410
15412
  super(...arguments);
15411
- this.isOpen = false;
15413
+ this.isOpen = (_b = (_a = this.options.expand) === null || _a === void 0 ? void 0 : _a.includes(this.facet.key)) !== null && _b !== void 0 ? _b : false;
15412
15414
  }
15413
15415
  get facetType() {
15414
15416
  switch (this.facet.type) {
@@ -15758,6 +15760,17 @@ const scrollTo = (elementId) => {
15758
15760
  top: el.offsetTop,
15759
15761
  behavior: "smooth",
15760
15762
  });
15763
+ };
15764
+ const disableBodyScroll = () => {
15765
+ const scrollY = window.scrollY;
15766
+ document.body.style.position = "fixed";
15767
+ document.body.style.top = `-${scrollY}px`;
15768
+ };
15769
+ const enableBodyScroll = () => {
15770
+ const scrollY = document.body.style.top;
15771
+ document.body.style.position = "";
15772
+ document.body.style.top = "";
15773
+ window.scrollTo(0, parseInt(scrollY || "0") * -1);
15761
15774
  };
15762
15775
 
15763
15776
  const searchResult$g = namespace("searchResult");
@@ -16276,15 +16289,15 @@ let MobileFilterSidebar = class MobileFilterSidebar extends Vue$1 {
16276
16289
  return !((_b = (_a = this.options.currentFilters) === null || _a === void 0 ? void 0 : _a.mobileSidebar) === null || _b === void 0 ? void 0 : _b.activeFiltersExpanded);
16277
16290
  }
16278
16291
  handleMobileToggle() {
16279
- this.setSidebarVisibility({ visible: false });
16292
+ this.setSidebarState({ visible: false });
16280
16293
  }
16281
16294
  };
16282
16295
  __decorate([
16283
16296
  Prop()
16284
16297
  ], MobileFilterSidebar.prototype, "options", void 0);
16285
16298
  __decorate([
16286
- searchResult$f.Mutation("setSidebarVisibility")
16287
- ], MobileFilterSidebar.prototype, "setSidebarVisibility", void 0);
16299
+ searchResult$f.Action("setSidebarState")
16300
+ ], MobileFilterSidebar.prototype, "setSidebarState", void 0);
16288
16301
  __decorate([
16289
16302
  searchResult$f.State((state) => state.isMobileSidebarVisible)
16290
16303
  ], MobileFilterSidebar.prototype, "isMobileSidebarVisible", void 0);
@@ -19104,7 +19117,7 @@ __vue_render__$f._withStripped = true;
19104
19117
  const searchResult$8 = namespace("searchResult");
19105
19118
  let SearchResultsMobileToggle = class SearchResultsMobileToggle extends Vue$1 {
19106
19119
  handleMobileToggle() {
19107
- this.setSidebarVisibility({ visible: true });
19120
+ this.setSidebarState({ visible: true });
19108
19121
  }
19109
19122
  };
19110
19123
  __decorate([
@@ -19117,8 +19130,8 @@ __decorate([
19117
19130
  searchResult$8.Getter("currentFilterCount")
19118
19131
  ], SearchResultsMobileToggle.prototype, "currentFilterCount", void 0);
19119
19132
  __decorate([
19120
- searchResult$8.Mutation("setSidebarVisibility")
19121
- ], SearchResultsMobileToggle.prototype, "setSidebarVisibility", void 0);
19133
+ searchResult$8.Action("setSidebarState")
19134
+ ], SearchResultsMobileToggle.prototype, "setSidebarState", void 0);
19122
19135
  SearchResultsMobileToggle = __decorate([
19123
19136
  Component({
19124
19137
  name: "searchResultsMobileToggle",
@@ -19817,6 +19830,11 @@ let SearchResultsProducts = class SearchResultsProducts extends Vue$1 {
19817
19830
  getProductKey(index, product) {
19818
19831
  return getProductKey(index, product, this.options.idKey);
19819
19832
  }
19833
+ goToFirstPage() {
19834
+ this.appendParams({
19835
+ params: [{ name: QUERY_PARAMS.PAGE, value: "1" }],
19836
+ });
19837
+ }
19820
19838
  };
19821
19839
  __decorate([
19822
19840
  Prop()
@@ -19830,6 +19848,9 @@ __decorate([
19830
19848
  __decorate([
19831
19849
  searchResult$4.Getter("currentQueryText")
19832
19850
  ], SearchResultsProducts.prototype, "currentQueryText", void 0);
19851
+ __decorate([
19852
+ searchResult$4.Getter("isPageEmpty")
19853
+ ], SearchResultsProducts.prototype, "isPageEmpty", void 0);
19833
19854
  __decorate([
19834
19855
  searchResult$4.State((state) => state.isMobileSidebarVisible)
19835
19856
  ], SearchResultsProducts.prototype, "isMobileSidebarVisible", void 0);
@@ -19848,6 +19869,9 @@ __decorate([
19848
19869
  __decorate([
19849
19870
  params$2.Getter("page")
19850
19871
  ], SearchResultsProducts.prototype, "page", void 0);
19872
+ __decorate([
19873
+ params$2.Action("appendParams")
19874
+ ], SearchResultsProducts.prototype, "appendParams", void 0);
19851
19875
  SearchResultsProducts = __decorate([
19852
19876
  Component({
19853
19877
  name: "searchResultsProducts",
@@ -19874,10 +19898,7 @@ var __vue_render__$8 = function () {
19874
19898
  var _c = _vm._self._c || _h;
19875
19899
  return _c(
19876
19900
  "div",
19877
- {
19878
- style: { display: _vm.isMobileSidebarVisible ? "none" : "block" },
19879
- attrs: { id: "lupa-search-results-products" },
19880
- },
19901
+ { attrs: { id: "lupa-search-results-products" } },
19881
19902
  [
19882
19903
  _vm.loading && !_vm.isMobileSidebarVisible
19883
19904
  ? _c("spinner", { staticClass: "lupa-loader" })
@@ -19945,6 +19966,38 @@ var __vue_render__$8 = function () {
19945
19966
  1
19946
19967
  ),
19947
19968
  _vm._v(" "),
19969
+ _vm.isPageEmpty && _vm.options.labels.noItemsInPage
19970
+ ? _c(
19971
+ "div",
19972
+ {
19973
+ staticClass: "lupa-empty-results",
19974
+ attrs: { "data-cy": "lupa-no-results-in-page" },
19975
+ },
19976
+ [
19977
+ _vm._v(
19978
+ "\n " +
19979
+ _vm._s(_vm.options.labels.noItemsInPage) +
19980
+ "\n "
19981
+ ),
19982
+ _vm.options.labels.backToFirstPage
19983
+ ? _c(
19984
+ "span",
19985
+ {
19986
+ staticClass: "lupa-empty-page-action",
19987
+ on: { click: _vm.goToFirstPage },
19988
+ },
19989
+ [
19990
+ _vm._v(
19991
+ "\n " +
19992
+ _vm._s(_vm.options.labels.backToFirstPage)
19993
+ ),
19994
+ ]
19995
+ )
19996
+ : _vm._e(),
19997
+ ]
19998
+ )
19999
+ : _vm._e(),
20000
+ _vm._v(" "),
19948
20001
  _c("SearchResultsToolbar", {
19949
20002
  staticClass: "lupa-toolbar-bottom",
19950
20003
  attrs: { options: _vm.options, "pagination-location": "bottom" },
@@ -20754,17 +20807,13 @@ __vue_render__$3._withStripped = true;
20754
20807
  );
20755
20808
 
20756
20809
  let CategoryDescription = class CategoryDescription extends Vue$1 {
20757
- get title() {
20758
- var _a, _b;
20759
- return (_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.title;
20760
- }
20761
20810
  get description() {
20762
20811
  var _a, _b;
20763
20812
  return (_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.description;
20764
20813
  }
20765
20814
  get overviewVisible() {
20766
20815
  var _a, _b;
20767
- return Boolean((_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.title);
20816
+ return Boolean((_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.description);
20768
20817
  }
20769
20818
  };
20770
20819
  __decorate([
@@ -20790,10 +20839,6 @@ var __vue_render__$2 = function () {
20790
20839
  var _c = _vm._self._c || _h;
20791
20840
  return _vm.overviewVisible
20792
20841
  ? _c("div", { staticClass: "lupa-category-overview" }, [
20793
- _c("div", { staticClass: "lupa-category-title" }, [
20794
- _vm._v(_vm._s(_vm.title)),
20795
- ]),
20796
- _vm._v(" "),
20797
20842
  _c("div", {
20798
20843
  staticClass: "lupa-category-description",
20799
20844
  domProps: { innerHTML: _vm._s(_vm.description) },
@@ -21661,6 +21706,20 @@ let SearchResultModule = class SearchResultModule extends VuexModule {
21661
21706
  return "xl";
21662
21707
  }
21663
21708
  }
21709
+ get isPageEmpty() {
21710
+ var _a;
21711
+ return (this.hasResults && ((_a = this.searchResult.offset) !== null && _a !== void 0 ? _a : 0) >= this.totalItems);
21712
+ }
21713
+ setSidebarState({ visible }) {
21714
+ // Disable body scroll when sidebar is open and preserve scroll position when scrolling is closed
21715
+ if (visible) {
21716
+ disableBodyScroll();
21717
+ }
21718
+ else {
21719
+ enableBodyScroll();
21720
+ }
21721
+ return { visible };
21722
+ }
21664
21723
  setSidebarVisibility({ visible }) {
21665
21724
  this.isMobileSidebarVisible = visible;
21666
21725
  }
@@ -21740,6 +21799,9 @@ let SearchResultModule = class SearchResultModule extends VuexModule {
21740
21799
  return loading || false;
21741
21800
  }
21742
21801
  };
21802
+ __decorate([
21803
+ Action({ commit: "setSidebarVisibility" })
21804
+ ], SearchResultModule.prototype, "setSidebarState", null);
21743
21805
  __decorate([
21744
21806
  Mutation
21745
21807
  ], SearchResultModule.prototype, "setSidebarVisibility", null);
@@ -21973,8 +22035,8 @@ let OptionsModule = class OptionsModule extends VuexModule {
21973
22035
  return (_b = (_a = this.currentResolutionPageSizes) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : DEFAULT_PAGE_SIZE;
21974
22036
  }
21975
22037
  get currentResolutionPageSizes() {
21976
- var _a, _b, _c;
21977
- const pageSizes = (_c = (_b = (_a = this.searchResultOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.sizeSelection) === null || _c === void 0 ? void 0 : _c.sizes;
22038
+ var _a, _b, _c, _d;
22039
+ const pageSizes = (_d = (_c = (_b = (_a = this.searchResultOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.sizeSelection) === null || _c === void 0 ? void 0 : _c.sizes) !== null && _d !== void 0 ? _d : DEFAULT_PAGE_SIZE_SELECTION;
21978
22040
  if (Array.isArray(pageSizes)) {
21979
22041
  return pageSizes;
21980
22042
  }
@@ -26,6 +26,12 @@ export default class SearchResultModule extends VuexModule {
26
26
  get itemRange(): number[];
27
27
  get isMobileWidth(): boolean;
28
28
  get currentScreenWidth(): ScreenSize;
29
+ get isPageEmpty(): boolean;
30
+ setSidebarState({ visible }: {
31
+ visible: boolean;
32
+ }): {
33
+ visible: boolean;
34
+ };
29
35
  setSidebarVisibility({ visible }: {
30
36
  visible: boolean;
31
37
  }): void;
@@ -39,6 +39,8 @@ export declare type SearchResultsOptionLabels = SearchResultsPaginationLabels &
39
39
  mobileFilterButton: string;
40
40
  htmlTitleTemplate: string;
41
41
  outOfStock?: string;
42
+ noItemsInPage?: string;
43
+ backToFirstPage?: string;
42
44
  };
43
45
  export declare type SearchResultsAdditionalPanels = {
44
46
  additionalPanels?: SearchResultsAdditionalPanelOptions[];
@@ -143,6 +145,7 @@ export declare type ResultFacetOptions = {
143
145
  type: FacetStyle;
144
146
  };
145
147
  exclude?: string[];
148
+ expand?: string[];
146
149
  facetFilterQueries?: Record<string, FacetFilterQuery>;
147
150
  };
148
151
  export declare type SearchResultsFilterOptions = {
@@ -1,2 +1,4 @@
1
1
  export declare const scrollToSearchResults: (timeout?: number) => void;
2
2
  export declare const scrollTo: (elementId: string) => void;
3
+ export declare const disableBodyScroll: () => void;
4
+ export declare const enableBodyScroll: () => void;
@@ -2,7 +2,6 @@ import Vue from "vue";
2
2
  import { ProductListOptions } from "@/types/product-list/ProductListOptions";
3
3
  export default class CategoryDescription extends Vue {
4
4
  options: ProductListOptions;
5
- get title(): string | undefined;
6
5
  get description(): string | undefined;
7
6
  get overviewVisible(): boolean;
8
7
  }
@@ -2,7 +2,7 @@ import { SearchResultsFilterOptions } from "@/types/search-results/SearchResults
2
2
  import Vue from "vue";
3
3
  export default class MobileFilterSidebar extends Vue {
4
4
  options: SearchResultsFilterOptions;
5
- setSidebarVisibility: ({ visible, }: {
5
+ setSidebarState: ({ visible, }: {
6
6
  visible: boolean;
7
7
  }) => void;
8
8
  isMobileSidebarVisible: boolean;
@@ -3,7 +3,7 @@ export default class SearchResultsMobileToggle extends Vue {
3
3
  label: string;
4
4
  showFilterCount: boolean;
5
5
  currentFilterCount: number;
6
- setSidebarVisibility: ({ visible, }: {
6
+ setSidebarState: ({ visible, }: {
7
7
  visible: boolean;
8
8
  }) => void;
9
9
  handleMobileToggle(): void;
@@ -8,6 +8,7 @@ export default class SearchResultsProducts extends Vue {
8
8
  loading: boolean;
9
9
  hasResults: boolean;
10
10
  currentQueryText: string;
11
+ isPageEmpty: boolean;
11
12
  isMobileSidebarVisible: boolean;
12
13
  productCardOptions(): SearchResultsProductCardOptions;
13
14
  get similarQueriesLabels(): SearchResultsSimilarQueriesLabels;
@@ -21,4 +22,11 @@ export default class SearchResultsProducts extends Vue {
21
22
  page: number;
22
23
  get columnSize(): string;
23
24
  getProductKey(index: string, product: Document): string;
25
+ appendParams: ({ params, }: {
26
+ params: {
27
+ name: string;
28
+ value: string;
29
+ }[];
30
+ }) => void;
31
+ goToFirstPage(): void;
24
32
  }
@@ -13,6 +13,8 @@ export declare const SEARCH_RESULTS_CONFIGURATION: {
13
13
  priceSeparator: string;
14
14
  showMore: string;
15
15
  emptyResults: string;
16
+ noItemsInPage: string;
17
+ backToFirstPage: string;
16
18
  mobileFilterButton: string;
17
19
  htmlTitleTemplate: string;
18
20
  noResultsSuggestion: string;
@@ -11,4 +11,5 @@ export declare const XL_MIN_WIDTH = 1199;
11
11
  export declare const MAX_FACET_VALUES = 5000;
12
12
  export declare const CURRENCY_KEY_INDICATOR = "price";
13
13
  export declare const DEFAULT_PAGE_SIZE = 12;
14
+ export declare const DEFAULT_PAGE_SIZE_SELECTION: number[];
14
15
  export declare const LUPA_ROUTING_EVENT = "lupaRedirect";
@@ -11915,6 +11915,7 @@ const XL_MIN_WIDTH = 1199;
11915
11915
  const MAX_FACET_VALUES = 5000;
11916
11916
  const CURRENCY_KEY_INDICATOR = "price";
11917
11917
  const DEFAULT_PAGE_SIZE = 12;
11918
+ const DEFAULT_PAGE_SIZE_SELECTION = [12, 24, 36, 60];
11918
11919
  const LUPA_ROUTING_EVENT = "lupaRedirect";
11919
11920
 
11920
11921
  const formatRange = (filter) => {
@@ -15403,8 +15404,9 @@ __vue_render__$J._withStripped = true;
15403
15404
  const searchResult$h = namespace("searchResult");
15404
15405
  let FacetDisplay = class FacetDisplay extends Vue$1 {
15405
15406
  constructor() {
15407
+ var _a, _b;
15406
15408
  super(...arguments);
15407
- this.isOpen = false;
15409
+ this.isOpen = (_b = (_a = this.options.expand) === null || _a === void 0 ? void 0 : _a.includes(this.facet.key)) !== null && _b !== void 0 ? _b : false;
15408
15410
  }
15409
15411
  get facetType() {
15410
15412
  switch (this.facet.type) {
@@ -15754,6 +15756,17 @@ const scrollTo = (elementId) => {
15754
15756
  top: el.offsetTop,
15755
15757
  behavior: "smooth",
15756
15758
  });
15759
+ };
15760
+ const disableBodyScroll = () => {
15761
+ const scrollY = window.scrollY;
15762
+ document.body.style.position = "fixed";
15763
+ document.body.style.top = `-${scrollY}px`;
15764
+ };
15765
+ const enableBodyScroll = () => {
15766
+ const scrollY = document.body.style.top;
15767
+ document.body.style.position = "";
15768
+ document.body.style.top = "";
15769
+ window.scrollTo(0, parseInt(scrollY || "0") * -1);
15757
15770
  };
15758
15771
 
15759
15772
  const searchResult$g = namespace("searchResult");
@@ -16272,15 +16285,15 @@ let MobileFilterSidebar = class MobileFilterSidebar extends Vue$1 {
16272
16285
  return !((_b = (_a = this.options.currentFilters) === null || _a === void 0 ? void 0 : _a.mobileSidebar) === null || _b === void 0 ? void 0 : _b.activeFiltersExpanded);
16273
16286
  }
16274
16287
  handleMobileToggle() {
16275
- this.setSidebarVisibility({ visible: false });
16288
+ this.setSidebarState({ visible: false });
16276
16289
  }
16277
16290
  };
16278
16291
  __decorate([
16279
16292
  Prop()
16280
16293
  ], MobileFilterSidebar.prototype, "options", void 0);
16281
16294
  __decorate([
16282
- searchResult$f.Mutation("setSidebarVisibility")
16283
- ], MobileFilterSidebar.prototype, "setSidebarVisibility", void 0);
16295
+ searchResult$f.Action("setSidebarState")
16296
+ ], MobileFilterSidebar.prototype, "setSidebarState", void 0);
16284
16297
  __decorate([
16285
16298
  searchResult$f.State((state) => state.isMobileSidebarVisible)
16286
16299
  ], MobileFilterSidebar.prototype, "isMobileSidebarVisible", void 0);
@@ -19100,7 +19113,7 @@ __vue_render__$f._withStripped = true;
19100
19113
  const searchResult$8 = namespace("searchResult");
19101
19114
  let SearchResultsMobileToggle = class SearchResultsMobileToggle extends Vue$1 {
19102
19115
  handleMobileToggle() {
19103
- this.setSidebarVisibility({ visible: true });
19116
+ this.setSidebarState({ visible: true });
19104
19117
  }
19105
19118
  };
19106
19119
  __decorate([
@@ -19113,8 +19126,8 @@ __decorate([
19113
19126
  searchResult$8.Getter("currentFilterCount")
19114
19127
  ], SearchResultsMobileToggle.prototype, "currentFilterCount", void 0);
19115
19128
  __decorate([
19116
- searchResult$8.Mutation("setSidebarVisibility")
19117
- ], SearchResultsMobileToggle.prototype, "setSidebarVisibility", void 0);
19129
+ searchResult$8.Action("setSidebarState")
19130
+ ], SearchResultsMobileToggle.prototype, "setSidebarState", void 0);
19118
19131
  SearchResultsMobileToggle = __decorate([
19119
19132
  Component({
19120
19133
  name: "searchResultsMobileToggle",
@@ -19813,6 +19826,11 @@ let SearchResultsProducts = class SearchResultsProducts extends Vue$1 {
19813
19826
  getProductKey(index, product) {
19814
19827
  return getProductKey(index, product, this.options.idKey);
19815
19828
  }
19829
+ goToFirstPage() {
19830
+ this.appendParams({
19831
+ params: [{ name: QUERY_PARAMS.PAGE, value: "1" }],
19832
+ });
19833
+ }
19816
19834
  };
19817
19835
  __decorate([
19818
19836
  Prop()
@@ -19826,6 +19844,9 @@ __decorate([
19826
19844
  __decorate([
19827
19845
  searchResult$4.Getter("currentQueryText")
19828
19846
  ], SearchResultsProducts.prototype, "currentQueryText", void 0);
19847
+ __decorate([
19848
+ searchResult$4.Getter("isPageEmpty")
19849
+ ], SearchResultsProducts.prototype, "isPageEmpty", void 0);
19829
19850
  __decorate([
19830
19851
  searchResult$4.State((state) => state.isMobileSidebarVisible)
19831
19852
  ], SearchResultsProducts.prototype, "isMobileSidebarVisible", void 0);
@@ -19844,6 +19865,9 @@ __decorate([
19844
19865
  __decorate([
19845
19866
  params$2.Getter("page")
19846
19867
  ], SearchResultsProducts.prototype, "page", void 0);
19868
+ __decorate([
19869
+ params$2.Action("appendParams")
19870
+ ], SearchResultsProducts.prototype, "appendParams", void 0);
19847
19871
  SearchResultsProducts = __decorate([
19848
19872
  Component({
19849
19873
  name: "searchResultsProducts",
@@ -19870,10 +19894,7 @@ var __vue_render__$8 = function () {
19870
19894
  var _c = _vm._self._c || _h;
19871
19895
  return _c(
19872
19896
  "div",
19873
- {
19874
- style: { display: _vm.isMobileSidebarVisible ? "none" : "block" },
19875
- attrs: { id: "lupa-search-results-products" },
19876
- },
19897
+ { attrs: { id: "lupa-search-results-products" } },
19877
19898
  [
19878
19899
  _vm.loading && !_vm.isMobileSidebarVisible
19879
19900
  ? _c("spinner", { staticClass: "lupa-loader" })
@@ -19941,6 +19962,38 @@ var __vue_render__$8 = function () {
19941
19962
  1
19942
19963
  ),
19943
19964
  _vm._v(" "),
19965
+ _vm.isPageEmpty && _vm.options.labels.noItemsInPage
19966
+ ? _c(
19967
+ "div",
19968
+ {
19969
+ staticClass: "lupa-empty-results",
19970
+ attrs: { "data-cy": "lupa-no-results-in-page" },
19971
+ },
19972
+ [
19973
+ _vm._v(
19974
+ "\n " +
19975
+ _vm._s(_vm.options.labels.noItemsInPage) +
19976
+ "\n "
19977
+ ),
19978
+ _vm.options.labels.backToFirstPage
19979
+ ? _c(
19980
+ "span",
19981
+ {
19982
+ staticClass: "lupa-empty-page-action",
19983
+ on: { click: _vm.goToFirstPage },
19984
+ },
19985
+ [
19986
+ _vm._v(
19987
+ "\n " +
19988
+ _vm._s(_vm.options.labels.backToFirstPage)
19989
+ ),
19990
+ ]
19991
+ )
19992
+ : _vm._e(),
19993
+ ]
19994
+ )
19995
+ : _vm._e(),
19996
+ _vm._v(" "),
19944
19997
  _c("SearchResultsToolbar", {
19945
19998
  staticClass: "lupa-toolbar-bottom",
19946
19999
  attrs: { options: _vm.options, "pagination-location": "bottom" },
@@ -20750,17 +20803,13 @@ __vue_render__$3._withStripped = true;
20750
20803
  );
20751
20804
 
20752
20805
  let CategoryDescription = class CategoryDescription extends Vue$1 {
20753
- get title() {
20754
- var _a, _b;
20755
- return (_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.title;
20756
- }
20757
20806
  get description() {
20758
20807
  var _a, _b;
20759
20808
  return (_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.description;
20760
20809
  }
20761
20810
  get overviewVisible() {
20762
20811
  var _a, _b;
20763
- return Boolean((_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.title);
20812
+ return Boolean((_b = (_a = this.options.categories) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.description);
20764
20813
  }
20765
20814
  };
20766
20815
  __decorate([
@@ -20786,10 +20835,6 @@ var __vue_render__$2 = function () {
20786
20835
  var _c = _vm._self._c || _h;
20787
20836
  return _vm.overviewVisible
20788
20837
  ? _c("div", { staticClass: "lupa-category-overview" }, [
20789
- _c("div", { staticClass: "lupa-category-title" }, [
20790
- _vm._v(_vm._s(_vm.title)),
20791
- ]),
20792
- _vm._v(" "),
20793
20838
  _c("div", {
20794
20839
  staticClass: "lupa-category-description",
20795
20840
  domProps: { innerHTML: _vm._s(_vm.description) },
@@ -21657,6 +21702,20 @@ let SearchResultModule = class SearchResultModule extends VuexModule {
21657
21702
  return "xl";
21658
21703
  }
21659
21704
  }
21705
+ get isPageEmpty() {
21706
+ var _a;
21707
+ return (this.hasResults && ((_a = this.searchResult.offset) !== null && _a !== void 0 ? _a : 0) >= this.totalItems);
21708
+ }
21709
+ setSidebarState({ visible }) {
21710
+ // Disable body scroll when sidebar is open and preserve scroll position when scrolling is closed
21711
+ if (visible) {
21712
+ disableBodyScroll();
21713
+ }
21714
+ else {
21715
+ enableBodyScroll();
21716
+ }
21717
+ return { visible };
21718
+ }
21660
21719
  setSidebarVisibility({ visible }) {
21661
21720
  this.isMobileSidebarVisible = visible;
21662
21721
  }
@@ -21736,6 +21795,9 @@ let SearchResultModule = class SearchResultModule extends VuexModule {
21736
21795
  return loading || false;
21737
21796
  }
21738
21797
  };
21798
+ __decorate([
21799
+ Action({ commit: "setSidebarVisibility" })
21800
+ ], SearchResultModule.prototype, "setSidebarState", null);
21739
21801
  __decorate([
21740
21802
  Mutation
21741
21803
  ], SearchResultModule.prototype, "setSidebarVisibility", null);
@@ -21969,8 +22031,8 @@ let OptionsModule = class OptionsModule extends VuexModule {
21969
22031
  return (_b = (_a = this.currentResolutionPageSizes) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : DEFAULT_PAGE_SIZE;
21970
22032
  }
21971
22033
  get currentResolutionPageSizes() {
21972
- var _a, _b, _c;
21973
- const pageSizes = (_c = (_b = (_a = this.searchResultOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.sizeSelection) === null || _c === void 0 ? void 0 : _c.sizes;
22034
+ var _a, _b, _c, _d;
22035
+ const pageSizes = (_d = (_c = (_b = (_a = this.searchResultOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.sizeSelection) === null || _c === void 0 ? void 0 : _c.sizes) !== null && _d !== void 0 ? _d : DEFAULT_PAGE_SIZE_SELECTION;
21974
22036
  if (Array.isArray(pageSizes)) {
21975
22037
  return pageSizes;
21976
22038
  }
@@ -26,6 +26,12 @@ export default class SearchResultModule extends VuexModule {
26
26
  get itemRange(): number[];
27
27
  get isMobileWidth(): boolean;
28
28
  get currentScreenWidth(): ScreenSize;
29
+ get isPageEmpty(): boolean;
30
+ setSidebarState({ visible }: {
31
+ visible: boolean;
32
+ }): {
33
+ visible: boolean;
34
+ };
29
35
  setSidebarVisibility({ visible }: {
30
36
  visible: boolean;
31
37
  }): void;
@@ -39,6 +39,8 @@ export declare type SearchResultsOptionLabels = SearchResultsPaginationLabels &
39
39
  mobileFilterButton: string;
40
40
  htmlTitleTemplate: string;
41
41
  outOfStock?: string;
42
+ noItemsInPage?: string;
43
+ backToFirstPage?: string;
42
44
  };
43
45
  export declare type SearchResultsAdditionalPanels = {
44
46
  additionalPanels?: SearchResultsAdditionalPanelOptions[];
@@ -143,6 +145,7 @@ export declare type ResultFacetOptions = {
143
145
  type: FacetStyle;
144
146
  };
145
147
  exclude?: string[];
148
+ expand?: string[];
146
149
  facetFilterQueries?: Record<string, FacetFilterQuery>;
147
150
  };
148
151
  export declare type SearchResultsFilterOptions = {
@@ -1,2 +1,4 @@
1
1
  export declare const scrollToSearchResults: (timeout?: number) => void;
2
2
  export declare const scrollTo: (elementId: string) => void;
3
+ export declare const disableBodyScroll: () => void;
4
+ export declare const enableBodyScroll: () => void;
@@ -2,7 +2,6 @@ import Vue from "vue";
2
2
  import { ProductListOptions } from "@/types/product-list/ProductListOptions";
3
3
  export default class CategoryDescription extends Vue {
4
4
  options: ProductListOptions;
5
- get title(): string | undefined;
6
5
  get description(): string | undefined;
7
6
  get overviewVisible(): boolean;
8
7
  }