@scayle/storefront-product-listing 0.1.2 → 0.1.4

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.
@@ -1,11 +1,13 @@
1
1
  import type { ProductSearchQuery } from '@scayle/storefront-nuxt';
2
+ import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
2
3
  export interface AppliedFiltersOptions {
3
4
  filtersPrefix: string;
4
5
  }
5
6
  /**
6
7
  * Composable to manage applied filters based on route query parameters.
7
8
  *
8
- * @param {object} options - Configuration options for applied filters.
9
+ * @param {RouteLocationNormalizedLoadedGeneric} [route] - Route object to handle the queries.
10
+ * @param {AppliedFiltersOptions} options - Configuration options for applied filters.
9
11
  * @param {string} options.filtersPrefix - The prefix used to identify filter-related query parameters.
10
12
  *
11
13
  * @returns {object} - An object containing the following properties:
@@ -28,7 +30,7 @@ export interface AppliedFiltersOptions {
28
30
  *
29
31
  * - `areFiltersApplied` {ComputedRef<boolean>}: A computed property that returns `true` if any filters are currently applied, otherwise `false`.
30
32
  */
31
- export declare function useAppliedFilters({ filtersPrefix }?: AppliedFiltersOptions): {
33
+ export declare function useAppliedFilters(route: RouteLocationNormalizedLoadedGeneric, { filtersPrefix }?: AppliedFiltersOptions): {
32
34
  appliedFilter: import("vue").ComputedRef<ProductSearchQuery>;
33
35
  appliedFiltersCount: import("vue").ComputedRef<number>;
34
36
  appliedAttributeValues: import("vue").ComputedRef<Record<string, (string | number)[]>>;
@@ -1,8 +1,6 @@
1
1
  import { computed } from "vue";
2
- import { useRoute } from "#app/composables/router";
3
2
  import { parseFilterDataFromRoute } from "../utils/filters.js";
4
- export function useAppliedFilters({ filtersPrefix } = { filtersPrefix: "filters" }) {
5
- const route = useRoute();
3
+ export function useAppliedFilters(route, { filtersPrefix } = { filtersPrefix: "filters" }) {
6
4
  const appliedFilter = computed(() => {
7
5
  return parseFilterDataFromRoute(route, filtersPrefix);
8
6
  });
@@ -1,6 +1,6 @@
1
1
  import { useFilters } from '@scayle/storefront-nuxt/composables';
2
2
  import { type ComputedRef, type MaybeRefOrGetter } from 'vue';
3
- import type { LocationQuery } from 'vue-router';
3
+ import type { LocationQuery, RouteLocationNormalizedLoadedGeneric } from 'vue-router';
4
4
  import type { FilterItemWithValues } from '../../types/filter.js';
5
5
  export type ProductListFilterOptions = Partial<{
6
6
  immediate: boolean;
@@ -14,8 +14,9 @@ type UseProductListFilterReturn = Pick<Awaited<ReturnType<typeof useFilters>>, '
14
14
  /**
15
15
  * Composable to manage filters based on current category ID and route query parameters.
16
16
  *
17
+ * @param {RouteLocationNormalizedLoadedGeneric} [route] - Route object to handle the queries.
17
18
  * @param {number} [currentCategoryId] - current/active category ID
18
- * @param {ProductListingFilterOptions} options - Configuration options for filters.
19
+ * @param {ProductListFilterOptions} options - Configuration options for filters.
19
20
  * @param {string} options.immediate - Will enable "immediate" flag via "useFilters" composable in it.
20
21
  * @param {string} options.keyPrefix - The prefix used to construct "key" via "useFilters" payload. Default is "base".
21
22
  *
@@ -28,5 +29,5 @@ type UseProductListFilterReturn = Pick<Awaited<ReturnType<typeof useFilters>>, '
28
29
  * - `unfilteredCount` {ComputedRef<number>}: returns unfiltered filters count.
29
30
  * - `clearedPriceQuery` {ComputedRef<LocationQuery | undefined>}: constructs an empty query object.
30
31
  */
31
- export declare function useProductListFilter(currentCategoryId?: MaybeRefOrGetter<number | undefined>, options?: ProductListFilterOptions): UseProductListFilterReturn & Promise<UseProductListFilterReturn>;
32
+ export declare function useProductListFilter(route: RouteLocationNormalizedLoadedGeneric, currentCategoryId?: MaybeRefOrGetter<number | undefined>, options?: ProductListFilterOptions): UseProductListFilterReturn & Promise<UseProductListFilterReturn>;
32
33
  export {};
@@ -2,12 +2,10 @@ import { extendPromise } from "@scayle/storefront-nuxt";
2
2
  import { useFilters } from "@scayle/storefront-nuxt/composables";
3
3
  import { computed, toValue } from "vue";
4
4
  import { getClearedPriceQuery } from "../utils/filters.js";
5
- import { useRoute } from "#app/composables/router";
6
5
  import { useAppliedFilters } from "./useAppliedFilters.js";
7
- export function useProductListFilter(currentCategoryId, options = {}) {
8
- const route = useRoute();
6
+ export function useProductListFilter(route, currentCategoryId, options = {}) {
9
7
  const { immediate = true, keyPrefix = "base" } = options;
10
- const { appliedFilter } = useAppliedFilters();
8
+ const { appliedFilter } = useAppliedFilters(route);
11
9
  const filterData = useFilters({
12
10
  params: computed(() => ({
13
11
  categoryId: toValue(currentCategoryId),
@@ -1,4 +1,5 @@
1
1
  import { APISortOption, APISortOrder, type ProductSortConfig } from '@scayle/storefront-nuxt';
2
+ import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
2
3
  type SelectedSort = ProductSortConfig & {
3
4
  key: string;
4
5
  label: string;
@@ -10,7 +11,8 @@ export interface ProductListSortOptions {
10
11
  /**
11
12
  * Custom composable to handle product list sorting.
12
13
  *
13
- * @param {ProductListOptions} [options] - Options for configuring the sorting behavior.
14
+ * @param {RouteLocationNormalizedLoadedGeneric} [route] - Route object to handle the queries and path.
15
+ * @param {ProductListSortOptions} [options] - Options for configuring the sorting behavior.
14
16
  * @param {SelectedSort[]} [options.sortingOptions] - Array of available sorting options.
15
17
  * @param {string} [options.defaultSortingKey] - Default sorting key to be applied if no specific sort is selected.
16
18
  * @returns - computed properties and methods related to sorting:
@@ -18,10 +20,11 @@ export interface ProductListSortOptions {
18
20
  * - {ComputedRef<SelectedSort[]>} sortLinks - Links with updated query parameters for each sorting option.
19
21
  * - {ComputedRef<boolean>} isDefaultSortSelected - Boolean indicating if the default sort is selected.
20
22
  */
21
- export declare function useProductListSort({ sortingOptions, defaultSortingKey }?: ProductListSortOptions): {
23
+ export declare function useProductListSort(route: RouteLocationNormalizedLoadedGeneric, { sortingOptions, defaultSortingKey }?: ProductListSortOptions): {
22
24
  selectedSort: import("vue").ComputedRef<SelectedSort | undefined>;
23
25
  sortLinks: import("vue").ComputedRef<{
24
26
  to: {
27
+ path: string;
25
28
  query: {
26
29
  sort: string;
27
30
  };
@@ -3,8 +3,7 @@ import {
3
3
  APISortOrder
4
4
  } from "@scayle/storefront-nuxt";
5
5
  import { computed } from "vue";
6
- import { useRoute } from "#app/composables/router";
7
- export function useProductListSort({ sortingOptions, defaultSortingKey } = {
6
+ export function useProductListSort(route, { sortingOptions, defaultSortingKey } = {
8
7
  sortingOptions: [
9
8
  {
10
9
  key: "top_seller",
@@ -39,7 +38,6 @@ export function useProductListSort({ sortingOptions, defaultSortingKey } = {
39
38
  ],
40
39
  defaultSortingKey: "top_seller"
41
40
  }) {
42
- const route = useRoute();
43
41
  const selectedSort = computed(() => {
44
42
  const sort = route.query.sort && sortingOptions?.find((option) => option.key === route.query.sort);
45
43
  if (!sort) {
@@ -52,6 +50,7 @@ export function useProductListSort({ sortingOptions, defaultSortingKey } = {
52
50
  return sortingOptions?.map((option) => ({
53
51
  ...option,
54
52
  to: {
53
+ path: route.path,
55
54
  query: { ...query, sort: option.key }
56
55
  }
57
56
  })) || [];
@@ -1,6 +1,7 @@
1
1
  import { type ComputedRef, type Ref } from 'vue';
2
2
  import type { BreadcrumbItem, Category } from '@scayle/storefront-nuxt';
3
3
  import type { BreadcrumbList, WithContext } from 'schema-dts';
4
+ import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
4
5
  type CanonicalLink = Record<'rel' | 'key' | 'href', string>;
5
6
  type UrlParams = Record<'baseUrl' | 'fullPath', string>;
6
7
  interface UseProductListingSeoData {
@@ -25,5 +26,5 @@ interface UseProductListingSeoData {
25
26
  * @property {ComputedRef<CanonicalLink[]>} canonicalLink - A computed canonical link.
26
27
  * @property {ComputedRef<WithContext<BreadcrumbList> | []>} categoryBreadcrumbSchema - A computed breadcrumb schema.
27
28
  */
28
- export declare function useProductListingSeoData(category: Ref<Category | undefined | null>, breadcrumbs: BreadcrumbItem[], { baseUrl, fullPath }: UrlParams): UseProductListingSeoData;
29
+ export declare function useProductListingSeoData(category: Ref<Category | undefined | null>, breadcrumbs: BreadcrumbItem[], route: RouteLocationNormalizedLoadedGeneric, { baseUrl, fullPath }: UrlParams): UseProductListingSeoData;
29
30
  export {};
@@ -5,9 +5,9 @@ import {
5
5
  } from "@scayle/storefront-nuxt";
6
6
  import { useAppliedFilters } from "./useAppliedFilters.js";
7
7
  import { useProductListSort } from "./useProductListSort.js";
8
- export function useProductListingSeoData(category, breadcrumbs, { baseUrl, fullPath }) {
9
- const { areFiltersApplied } = useAppliedFilters();
10
- const { isDefaultSortSelected } = useProductListSort();
8
+ export function useProductListingSeoData(category, breadcrumbs, route, { baseUrl, fullPath }) {
9
+ const { areFiltersApplied } = useAppliedFilters(route);
10
+ const { isDefaultSortSelected } = useProductListSort(route);
11
11
  const robots = computed(() => {
12
12
  return !areFiltersApplied.value && isDefaultSortSelected.value ? "index,follow" : "noindex,follow";
13
13
  });
@@ -1,8 +1,8 @@
1
1
  import { type FetchProductsByCategoryParams, type Product, type ProductWith } from '@scayle/storefront-nuxt';
2
- import type { LocationQuery } from 'vue-router';
3
2
  import { type MaybeRefOrGetter, type ComputedRef } from 'vue';
4
3
  import { useProducts } from '@scayle/storefront-nuxt/composables';
5
4
  import type { Pagination } from '@scayle/storefront-api';
5
+ import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
6
6
  type UseProductsByCategoryReturn = Pick<Awaited<ReturnType<typeof useProducts>>, 'error' | 'fetching'> & {
7
7
  products: ComputedRef<Product[]>;
8
8
  pagination: ComputedRef<Pagination | undefined>;
@@ -13,6 +13,7 @@ type UseProductsByCategoryReturn = Pick<Awaited<ReturnType<typeof useProducts>>,
13
13
  * Composable to fetch and manage products by category with configurable options.
14
14
  *
15
15
  * @param {MaybeRefOrGetter<number>} categoryId - The ID of the category to fetch products for. Accepts a ref, computed, or static number.
16
+ * @param {RouteLocationNormalizedLoadedGeneric} [route] - Route object to handle the queries.
16
17
  * @param {ProductsByCategoryOptions} options - Configuration options for fetching products.
17
18
  * @param {Partial<FetchProductsByCategoryParams>} options.params - Parameters to control product fetch behavior, excluding `category` and `categoryId`.
18
19
  * @param {Partial<{ lazy: boolean; immediate: boolean }>} options.fetchingOptions - Options for fetch timing, such as lazy loading or immediate fetching.
@@ -41,7 +42,6 @@ export interface ProductsByCategoryOptions {
41
42
  cacheKeyPrefix: string;
42
43
  fetchingKey?: string;
43
44
  withParams?: ProductWith;
44
- query: LocationQuery;
45
45
  }
46
- export declare function useProductsByCategory(categoryId: MaybeRefOrGetter<number>, { params, withParams, cacheKeyPrefix, fetchingKey, fetchingOptions, fetchProductsCacheTtl, productsPerPage, query, }?: Partial<ProductsByCategoryOptions>): UseProductsByCategoryReturn & Promise<UseProductsByCategoryReturn>;
46
+ export declare function useProductsByCategory(categoryId: MaybeRefOrGetter<number>, route: RouteLocationNormalizedLoadedGeneric, { params, withParams, cacheKeyPrefix, fetchingKey, fetchingOptions, fetchProductsCacheTtl, productsPerPage, }?: Partial<ProductsByCategoryOptions>): UseProductsByCategoryReturn & Promise<UseProductsByCategoryReturn>;
47
47
  export {};
@@ -8,15 +8,14 @@ import { useAppliedFilters } from "./useAppliedFilters.js";
8
8
  const PRODUCTS_PER_PAGE = 24;
9
9
  const DEFAULT_CACHE_TTL = 1e3;
10
10
  const DEFAULT_CACHE_KEY_PREFIX = "PLP";
11
- export function useProductsByCategory(categoryId, {
11
+ export function useProductsByCategory(categoryId, route, {
12
12
  params,
13
13
  withParams,
14
14
  cacheKeyPrefix,
15
15
  fetchingKey,
16
16
  fetchingOptions,
17
17
  fetchProductsCacheTtl,
18
- productsPerPage,
19
- query
18
+ productsPerPage
20
19
  } = {
21
20
  params: {
22
21
  includeSoldOut: false,
@@ -28,13 +27,13 @@ export function useProductsByCategory(categoryId, {
28
27
  fetchProductsCacheTtl: DEFAULT_CACHE_TTL,
29
28
  cacheKeyPrefix: DEFAULT_CACHE_KEY_PREFIX
30
29
  }) {
31
- const { selectedSort } = useProductListSort();
32
- const { appliedFilter } = useAppliedFilters();
30
+ const { selectedSort } = useProductListSort(route);
31
+ const { appliedFilter } = useAppliedFilters(route);
33
32
  const productsData = useProducts({
34
33
  params: () => ({
35
- ...query?.page && { page: +query.page },
34
+ ...route?.query.page && { page: +route?.query.page },
36
35
  sort: selectedSort.value,
37
- perPage: query?.products_per_page ? parseInt(query.products_per_page, 10) : productsPerPage,
36
+ perPage: route?.query.products_per_page ? parseInt(route?.query.products_per_page, 10) : productsPerPage,
38
37
  with: withParams,
39
38
  categoryId: toValue(categoryId),
40
39
  includeSoldOut: params?.includeSoldOut,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scayle/storefront-product-listing",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Collection of essential composables and utilities to work with product listing",
5
5
  "author": "SCAYLE Commerce Engine",
6
6
  "license": "MIT",
@@ -63,12 +63,12 @@
63
63
  "@vueuse/core": "11.2.0",
64
64
  "dprint": "0.47.5",
65
65
  "eslint": "9.14.0",
66
- "happy-dom": "15.11.4",
66
+ "happy-dom": "15.11.6",
67
67
  "eslint-formatter-gitlab": "5.1.0",
68
68
  "nuxt": "3.13.2",
69
69
  "publint": "0.2.12",
70
70
  "typescript": "5.6.3",
71
- "vitest": "2.1.4",
71
+ "vitest": "2.1.5",
72
72
  "schema-dts": "1.1.2",
73
73
  "vue-router": "4.4.5",
74
74
  "fishery": "2.2.2",