@wix/headless-stores 0.0.35 → 0.0.37

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 (131) hide show
  1. package/cjs/dist/react/Category.d.ts +83 -31
  2. package/cjs/dist/react/Category.js +68 -35
  3. package/cjs/dist/react/CategoryList.d.ts +184 -0
  4. package/cjs/dist/react/CategoryList.js +174 -0
  5. package/cjs/dist/react/Product.d.ts +3 -3
  6. package/cjs/dist/react/Product.js +6 -6
  7. package/cjs/dist/react/ProductActions.d.ts +1 -1
  8. package/cjs/dist/react/ProductActions.js +2 -2
  9. package/{dist/react/ProductsList.d.ts → cjs/dist/react/ProductList.d.ts} +71 -38
  10. package/{dist/react/ProductsList.js → cjs/dist/react/ProductList.js} +30 -26
  11. package/cjs/dist/react/ProductListFilters.d.ts +244 -0
  12. package/cjs/dist/react/ProductListFilters.js +216 -0
  13. package/cjs/dist/react/ProductListPagination.d.ts +246 -0
  14. package/cjs/dist/react/ProductListPagination.js +207 -0
  15. package/cjs/dist/react/ProductListSort.d.ts +87 -0
  16. package/cjs/dist/react/ProductListSort.js +85 -0
  17. package/cjs/dist/react/ProductModifiers.d.ts +5 -5
  18. package/cjs/dist/react/ProductModifiers.js +10 -10
  19. package/cjs/dist/react/ProductVariantSelector.d.ts +5 -5
  20. package/cjs/dist/react/ProductVariantSelector.js +13 -10
  21. package/cjs/dist/react/SelectedVariant.d.ts +3 -3
  22. package/cjs/dist/react/SelectedVariant.js +6 -6
  23. package/cjs/dist/react/index.d.ts +7 -9
  24. package/cjs/dist/react/index.js +7 -9
  25. package/cjs/dist/services/buy-now-service.d.ts +208 -0
  26. package/cjs/dist/services/buy-now-service.js +132 -1
  27. package/cjs/dist/services/categories-list-service.d.ts +163 -0
  28. package/cjs/dist/services/categories-list-service.js +148 -0
  29. package/cjs/dist/services/category-service.d.ts +115 -70
  30. package/cjs/dist/services/category-service.js +101 -110
  31. package/cjs/dist/services/index.d.ts +6 -7
  32. package/cjs/dist/services/index.js +5 -16
  33. package/cjs/dist/services/pay-now-service.d.ts +146 -0
  34. package/cjs/dist/services/pay-now-service.js +112 -1
  35. package/cjs/dist/services/product-service.d.ts +71 -0
  36. package/cjs/dist/services/product-service.js +47 -0
  37. package/cjs/dist/services/products-list-filters-service.d.ts +292 -0
  38. package/cjs/dist/services/products-list-filters-service.js +446 -0
  39. package/cjs/dist/services/products-list-pagination-service.d.ts +186 -0
  40. package/cjs/dist/services/products-list-pagination-service.js +179 -0
  41. package/cjs/dist/services/products-list-service.d.ts +138 -52
  42. package/cjs/dist/services/products-list-service.js +98 -51
  43. package/cjs/dist/services/products-list-sort-service.d.ts +117 -0
  44. package/cjs/dist/services/products-list-sort-service.js +144 -0
  45. package/cjs/dist/services/selected-variant-service.js +0 -1
  46. package/cjs/dist/utils/url-params.d.ts +68 -0
  47. package/cjs/dist/utils/url-params.js +72 -4
  48. package/dist/react/Category.d.ts +83 -31
  49. package/dist/react/Category.js +68 -35
  50. package/dist/react/CategoryList.d.ts +184 -0
  51. package/dist/react/CategoryList.js +174 -0
  52. package/dist/react/Product.d.ts +3 -3
  53. package/dist/react/Product.js +6 -6
  54. package/dist/react/ProductActions.d.ts +1 -1
  55. package/dist/react/ProductActions.js +2 -2
  56. package/{cjs/dist/react/ProductsList.d.ts → dist/react/ProductList.d.ts} +71 -38
  57. package/{cjs/dist/react/ProductsList.js → dist/react/ProductList.js} +30 -26
  58. package/dist/react/ProductListFilters.d.ts +244 -0
  59. package/dist/react/ProductListFilters.js +216 -0
  60. package/dist/react/ProductListPagination.d.ts +246 -0
  61. package/dist/react/ProductListPagination.js +207 -0
  62. package/dist/react/ProductListSort.d.ts +87 -0
  63. package/dist/react/ProductListSort.js +85 -0
  64. package/dist/react/ProductModifiers.d.ts +5 -5
  65. package/dist/react/ProductModifiers.js +10 -10
  66. package/dist/react/ProductVariantSelector.d.ts +5 -5
  67. package/dist/react/ProductVariantSelector.js +13 -10
  68. package/dist/react/SelectedVariant.d.ts +3 -3
  69. package/dist/react/SelectedVariant.js +6 -6
  70. package/dist/react/index.d.ts +7 -9
  71. package/dist/react/index.js +7 -9
  72. package/dist/services/buy-now-service.d.ts +208 -0
  73. package/dist/services/buy-now-service.js +132 -1
  74. package/dist/services/categories-list-service.d.ts +163 -0
  75. package/dist/services/categories-list-service.js +148 -0
  76. package/dist/services/category-service.d.ts +115 -70
  77. package/dist/services/category-service.js +101 -110
  78. package/dist/services/index.d.ts +6 -7
  79. package/dist/services/index.js +5 -16
  80. package/dist/services/pay-now-service.d.ts +146 -0
  81. package/dist/services/pay-now-service.js +112 -1
  82. package/dist/services/product-service.d.ts +71 -0
  83. package/dist/services/product-service.js +47 -0
  84. package/dist/services/products-list-filters-service.d.ts +292 -0
  85. package/dist/services/products-list-filters-service.js +446 -0
  86. package/dist/services/products-list-pagination-service.d.ts +186 -0
  87. package/dist/services/products-list-pagination-service.js +179 -0
  88. package/dist/services/products-list-service.d.ts +138 -52
  89. package/dist/services/products-list-service.js +98 -51
  90. package/dist/services/products-list-sort-service.d.ts +117 -0
  91. package/dist/services/products-list-sort-service.js +144 -0
  92. package/dist/services/selected-variant-service.js +0 -1
  93. package/dist/utils/url-params.d.ts +68 -0
  94. package/dist/utils/url-params.js +72 -4
  95. package/package.json +3 -3
  96. package/cjs/dist/react/Collection.d.ts +0 -294
  97. package/cjs/dist/react/Collection.js +0 -345
  98. package/cjs/dist/react/FilteredCollection.d.ts +0 -216
  99. package/cjs/dist/react/FilteredCollection.js +0 -256
  100. package/cjs/dist/react/RelatedProducts.d.ts +0 -169
  101. package/cjs/dist/react/RelatedProducts.js +0 -180
  102. package/cjs/dist/react/Sort.d.ts +0 -37
  103. package/cjs/dist/react/Sort.js +0 -36
  104. package/cjs/dist/services/catalog-service.d.ts +0 -36
  105. package/cjs/dist/services/catalog-service.js +0 -193
  106. package/cjs/dist/services/collection-service.d.ts +0 -124
  107. package/cjs/dist/services/collection-service.js +0 -628
  108. package/cjs/dist/services/filter-service.d.ts +0 -35
  109. package/cjs/dist/services/filter-service.js +0 -119
  110. package/cjs/dist/services/related-products-service.d.ts +0 -100
  111. package/cjs/dist/services/related-products-service.js +0 -127
  112. package/cjs/dist/services/sort-service.d.ts +0 -20
  113. package/cjs/dist/services/sort-service.js +0 -27
  114. package/dist/react/Collection.d.ts +0 -294
  115. package/dist/react/Collection.js +0 -345
  116. package/dist/react/FilteredCollection.d.ts +0 -216
  117. package/dist/react/FilteredCollection.js +0 -256
  118. package/dist/react/RelatedProducts.d.ts +0 -169
  119. package/dist/react/RelatedProducts.js +0 -180
  120. package/dist/react/Sort.d.ts +0 -37
  121. package/dist/react/Sort.js +0 -36
  122. package/dist/services/catalog-service.d.ts +0 -36
  123. package/dist/services/catalog-service.js +0 -193
  124. package/dist/services/collection-service.d.ts +0 -124
  125. package/dist/services/collection-service.js +0 -628
  126. package/dist/services/filter-service.d.ts +0 -35
  127. package/dist/services/filter-service.js +0 -119
  128. package/dist/services/related-products-service.d.ts +0 -100
  129. package/dist/services/related-products-service.js +0 -127
  130. package/dist/services/sort-service.d.ts +0 -20
  131. package/dist/services/sort-service.js +0 -27
@@ -0,0 +1,148 @@
1
+ import { defineService, implementService } from "@wix/services-definitions";
2
+ import { SignalsServiceDefinition, } from "@wix/services-definitions/core-services/signals";
3
+ import { categories } from "@wix/categories";
4
+ /**
5
+ * Service definition for the Categories List service.
6
+ * This defines the reactive API contract for managing a list of product categories.
7
+ *
8
+ * @constant
9
+ */
10
+ export const CategoriesListServiceDefinition = defineService("categories-list");
11
+ /**
12
+ * Implementation of the Categories List service that manages reactive categories data.
13
+ * This service provides signals for categories data, loading state, and error handling.
14
+ * The service is initialized with pre-loaded categories and maintains them in reactive signals.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { CategoriesListService, CategoriesListServiceDefinition } from '@wix/stores/services';
19
+ * import { useService } from '@wix/services-manager-react';
20
+ *
21
+ * function CategoriesComponent({ categoriesConfig }) {
22
+ * return (
23
+ * <ServiceProvider services={createServicesMap([
24
+ * [CategoriesListServiceDefinition, CategoriesListService.withConfig(categoriesConfig)]
25
+ * ])}>
26
+ * <CategoriesDisplay />
27
+ * </ServiceProvider>
28
+ * );
29
+ * }
30
+ *
31
+ * function CategoriesDisplay() {
32
+ * const categoriesService = useService(CategoriesListServiceDefinition);
33
+ * const categories = categoriesService.categories.get();
34
+ * const isLoading = categoriesService.isLoading.get();
35
+ * const error = categoriesService.error.get();
36
+ *
37
+ * if (isLoading) return <div>Loading categories...</div>;
38
+ * if (error) return <div>Error: {error}</div>;
39
+ *
40
+ * return (
41
+ * <ul>
42
+ * {categories.map(category => (
43
+ * <li key={category._id}>{category.name}</li>
44
+ * ))}
45
+ * </ul>
46
+ * );
47
+ * }
48
+ * ```
49
+ */
50
+ export const CategoriesListService = implementService.withConfig()(CategoriesListServiceDefinition, ({ getService, config }) => {
51
+ const signalsService = getService(SignalsServiceDefinition);
52
+ const categoriesSignal = signalsService.signal(config.categories);
53
+ const isLoadingSignal = signalsService.signal(false);
54
+ const errorSignal = signalsService.signal(null);
55
+ return {
56
+ categories: categoriesSignal,
57
+ isLoading: isLoadingSignal,
58
+ error: errorSignal,
59
+ };
60
+ });
61
+ /**
62
+ * Loads categories list service configuration from the Wix Categories API for SSR initialization.
63
+ * This function is designed to be used during Server-Side Rendering (SSR) to preload
64
+ * all visible product categories. The "all-products" category is automatically moved to the front of the list.
65
+ *
66
+ * @returns {Promise<CategoriesListServiceConfig>} Promise that resolves to the categories configuration
67
+ *
68
+ * @example
69
+ * ```astro
70
+ * ---
71
+ * // Astro page example - pages/categories.astro
72
+ * import { loadCategoriesListServiceConfig } from '@wix/stores/services';
73
+ * import { CategoryList } from '@wix/stores/components';
74
+ *
75
+ * // Load categories data during SSR
76
+ * const categoriesConfig = await loadCategoriesListServiceConfig();
77
+ * ---
78
+ *
79
+ * <CategoryList.Root categoriesConfig={categoriesConfig}>
80
+ * <CategoryList.ItemContent>
81
+ * {({ category }) => (
82
+ * <div>
83
+ * <h3>{category.name}</h3>
84
+ * <p>{category.description}</p>
85
+ * </div>
86
+ * )}
87
+ * </CategoryList.ItemContent>
88
+ * </CategoryList.Root>
89
+ * ```
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * // Next.js page example - pages/categories.tsx
94
+ * import { GetServerSideProps } from 'next';
95
+ * import { loadCategoriesListServiceConfig } from '@wix/stores/services';
96
+ * import { CategoryList } from '@wix/stores/components';
97
+ *
98
+ * interface CategoriesPageProps {
99
+ * categoriesConfig: Awaited<ReturnType<typeof loadCategoriesListServiceConfig>>;
100
+ * }
101
+ *
102
+ * export const getServerSideProps: GetServerSideProps<CategoriesPageProps> = async () => {
103
+ * const categoriesConfig = await loadCategoriesListServiceConfig();
104
+ *
105
+ * return {
106
+ * props: {
107
+ * categoriesConfig,
108
+ * },
109
+ * };
110
+ * };
111
+ *
112
+ * export default function CategoriesPage({ categoriesConfig }: CategoriesPageProps) {
113
+ * return (
114
+ * <CategoryList.Root categoriesConfig={categoriesConfig}>
115
+ * <CategoryList.ItemContent>
116
+ * {({ category }) => (
117
+ * <div>
118
+ * <h3>{category.name}</h3>
119
+ * <p>{category.description}</p>
120
+ * </div>
121
+ * )}
122
+ * </CategoryList.ItemContent>
123
+ * </CategoryList.Root>
124
+ * );
125
+ * }
126
+ * ```
127
+ */
128
+ export async function loadCategoriesListServiceConfig() {
129
+ const categoriesResponse = await categories
130
+ .queryCategories({
131
+ treeReference: {
132
+ appNamespace: "@wix/stores",
133
+ treeKey: null,
134
+ },
135
+ })
136
+ .eq("visible", true)
137
+ .find();
138
+ const fetchedCategories = categoriesResponse.items || [];
139
+ // Sort categories to put "all-products" first, keep the rest in original order
140
+ const allProductsCategory = fetchedCategories.find((cat) => cat.slug === "all-products");
141
+ const otherCategories = fetchedCategories.filter((cat) => cat.slug !== "all-products");
142
+ const allCategories = allProductsCategory
143
+ ? [allProductsCategory, ...otherCategories]
144
+ : fetchedCategories;
145
+ return {
146
+ categories: allCategories,
147
+ };
148
+ }
@@ -1,113 +1,158 @@
1
+ import { categories } from "@wix/categories";
1
2
  import { type Signal } from "@wix/services-definitions/core-services/signals";
2
- import * as categories from "@wix/auto_sdk_categories_categories";
3
- export interface CategoryServiceAPI {
4
- selectedCategory: Signal<string | null>;
5
- categories: Signal<categories.Category[]>;
6
- setSelectedCategory: (categoryId: string | null) => void;
7
- loadCategories: () => Promise<void>;
8
- }
3
+ /**
4
+ * Service definition for the Category service.
5
+ * This defines the reactive API contract for managing a single product category.
6
+ *
7
+ * @constant
8
+ */
9
9
  export declare const CategoryServiceDefinition: string & {
10
- __api: CategoryServiceAPI;
10
+ __api: {
11
+ /** Reactive signal containing the current category data */
12
+ category: Signal<categories.Category>;
13
+ };
11
14
  __config: {};
12
15
  isServiceDefinition?: boolean;
13
- } & CategoryServiceAPI;
14
- export interface CategoryServiceConfig {
15
- categories: categories.Category[];
16
- initialCategoryId?: string | null;
17
- onCategoryChange?: (categoryId: string | null, category: categories.Category | null) => void;
18
- }
16
+ } & {
17
+ /** Reactive signal containing the current category data */
18
+ category: Signal<categories.Category>;
19
+ };
20
+ /**
21
+ * Configuration interface for the Category service.
22
+ * Contains the initial category data that will be loaded into the service.
23
+ *
24
+ * @interface CategoryServiceConfig
25
+ */
26
+ export type CategoryServiceConfig = {
27
+ /** The category object to initialize the service with */
28
+ category: categories.Category;
29
+ };
30
+ /**
31
+ * Implementation of the Category service that manages reactive category data.
32
+ * This service provides a signal for category data and maintains it in a reactive state.
33
+ * The service is initialized with pre-loaded category data.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * import { CategoryService, CategoryServiceDefinition } from '@wix/stores/services';
38
+ * import { useService } from '@wix/services-manager-react';
39
+ *
40
+ * function CategoryComponent({ categoryConfig }) {
41
+ * return (
42
+ * <ServiceProvider services={createServicesMap([
43
+ * [CategoryServiceDefinition, CategoryService.withConfig(categoryConfig)]
44
+ * ])}>
45
+ * <CategoryDisplay />
46
+ * </ServiceProvider>
47
+ * );
48
+ * }
49
+ *
50
+ * function CategoryDisplay() {
51
+ * const categoryService = useService(CategoryServiceDefinition);
52
+ * const category = categoryService.category.get();
53
+ *
54
+ * return (
55
+ * <div>
56
+ * <h1>{category.name}</h1>
57
+ * <p>{category.description}</p>
58
+ * </div>
59
+ * );
60
+ * }
61
+ * ```
62
+ */
19
63
  export declare const CategoryService: import("@wix/services-definitions").ServiceFactory<string & {
20
- __api: CategoryServiceAPI;
64
+ __api: {
65
+ /** Reactive signal containing the current category data */
66
+ category: Signal<categories.Category>;
67
+ };
21
68
  __config: {};
22
69
  isServiceDefinition?: boolean;
23
- } & CategoryServiceAPI, CategoryServiceConfig>;
70
+ } & {
71
+ /** Reactive signal containing the current category data */
72
+ category: Signal<categories.Category>;
73
+ }, CategoryServiceConfig>;
24
74
  /**
25
- * Loads categories configuration from the Wix Categories API for SSR initialization.
75
+ * Loads category service configuration from the Wix Categories API for SSR initialization.
26
76
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
27
- * initial categories data that will be passed to the Category.Root component.
28
- * Fetches all visible categories and sorts them with "all-products" category first.
77
+ * a specific category by slug that will be used to configure the CategoryService.
29
78
  *
30
- * @returns Promise that resolves to an object containing categories array
79
+ * @param {string} slug - The category slug to load
80
+ * @returns {Promise} Promise that resolves to either success with config or not-found result
31
81
  *
32
82
  * @example
33
83
  * ```astro
34
84
  * ---
35
- * // Astro page example - pages/categories.astro
36
- * import { loadCategoriesConfig } from '@wix/stores/services';
85
+ * // Astro page example - pages/category/[slug].astro
86
+ * import { loadCategoryServiceConfig } from '@wix/stores/services';
37
87
  * import { Category } from '@wix/stores/components';
38
88
  *
39
- * // Load categories data during SSR
40
- * const categoryConfig = await loadCategoriesConfig();
89
+ * // Get category slug from URL params
90
+ * const { slug } = Astro.params;
91
+ *
92
+ * // Load category data during SSR
93
+ * const categoryResult = await loadCategoryServiceConfig(slug);
94
+ *
95
+ * // Handle not found case
96
+ * if (categoryResult.type === 'not-found') {
97
+ * return Astro.redirect('/404');
98
+ * }
41
99
  * ---
42
100
  *
43
- * <Category.Root categoryConfig={categoryConfig}>
44
- * <Category.List>
45
- * {({ categories, selectedCategory, setSelectedCategory }) => (
46
- * <nav className="category-nav">
47
- * <h2>Shop by Category</h2>
48
- * {categories.map(category => (
49
- * <button
50
- * key={category.id}
51
- * onClick={() => setSelectedCategory(category.id)}
52
- * className={selectedCategory === category.id ? 'active' : ''}
53
- * >
54
- * {category.name}
55
- * </button>
56
- * ))}
57
- * </nav>
58
- * )}
59
- * </Category.List>
101
+ * <Category.Root categoryConfig={categoryResult.config}>
102
+ * <Category.Name>
103
+ * {({ name }) => <h1>{name}</h1>}
104
+ * </Category.Name>
60
105
  * </Category.Root>
61
106
  * ```
62
107
  *
63
108
  * @example
64
109
  * ```tsx
65
- * // Next.js page example - pages/categories.tsx
110
+ * // Next.js page example - pages/category/[slug].tsx
66
111
  * import { GetServerSideProps } from 'next';
67
- * import { loadCategoriesConfig } from '@wix/stores/services';
112
+ * import { loadCategoryServiceConfig } from '@wix/stores/services';
68
113
  * import { Category } from '@wix/stores/components';
69
114
  *
70
115
  * interface CategoryPageProps {
71
- * categoryConfig: Awaited<ReturnType<typeof loadCategoriesConfig>>;
116
+ * categoryConfig: Awaited<ReturnType<typeof loadCategoryServiceConfig>>['config'];
72
117
  * }
73
118
  *
74
- * export const getServerSideProps: GetServerSideProps<CategoryPageProps> = async () => {
75
- * // Load categories data during SSR
76
- * const categoryConfig = await loadCategoriesConfig();
119
+ * export const getServerSideProps: GetServerSideProps<CategoryPageProps> = async ({ params }) => {
120
+ * const slug = params?.slug as string;
121
+ *
122
+ * // Load category data during SSR
123
+ * const categoryResult = await loadCategoryServiceConfig(slug);
124
+ *
125
+ * // Handle not found case
126
+ * if (categoryResult.type === 'not-found') {
127
+ * return {
128
+ * notFound: true,
129
+ * };
130
+ * }
77
131
  *
78
132
  * return {
79
133
  * props: {
80
- * categoryConfig,
134
+ * categoryConfig: categoryResult.config,
81
135
  * },
82
136
  * };
83
137
  * };
84
138
  *
85
139
  * export default function CategoryPage({ categoryConfig }: CategoryPageProps) {
86
140
  * return (
87
- * <div>
88
- * <h1>Product Categories</h1>
89
- * <Category.Root categoryConfig={categoryConfig}>
90
- * <Category.List>
91
- * {({ categories, selectedCategory, setSelectedCategory }) => (
92
- * <nav className="category-nav">
93
- * {categories.map(category => (
94
- * <button
95
- * key={category.id}
96
- * onClick={() => setSelectedCategory(category.id)}
97
- * className={`category-btn ${selectedCategory === category.id ? 'active' : ''}`}
98
- * >
99
- * {category.name}
100
- * </button>
101
- * ))}
102
- * </nav>
103
- * )}
104
- * </Category.List>
105
- * </Category.Root>
106
- * </div>
141
+ * <Category.Root categoryConfig={categoryConfig}>
142
+ * <Category.Name>
143
+ * {({ name }) => <h1>{name}</h1>}
144
+ * </Category.Name>
145
+ * </Category.Root>
107
146
  * );
108
147
  * }
109
148
  * ```
110
149
  */
111
- export declare function loadCategoriesConfig(): Promise<{
112
- categories: categories.Category[];
150
+ export declare function loadCategoryServiceConfig(slug: string): Promise<{
151
+ /** Type "success" means that the category was found and the config is valid */
152
+ type: "success";
153
+ /** The category config containing the loaded category data */
154
+ config: CategoryServiceConfig;
155
+ } | {
156
+ /** Type "not-found" means that the category was not found */
157
+ type: "not-found";
113
158
  }>;
@@ -1,156 +1,147 @@
1
1
  import { defineService, implementService } from "@wix/services-definitions";
2
+ import { categories } from "@wix/categories";
2
3
  import { SignalsServiceDefinition, } from "@wix/services-definitions/core-services/signals";
3
- import * as categories from "@wix/auto_sdk_categories_categories";
4
- export const CategoryServiceDefinition = defineService("category-service");
4
+ /**
5
+ * Service definition for the Category service.
6
+ * This defines the reactive API contract for managing a single product category.
7
+ *
8
+ * @constant
9
+ */
10
+ export const CategoryServiceDefinition = defineService("category");
11
+ /**
12
+ * Implementation of the Category service that manages reactive category data.
13
+ * This service provides a signal for category data and maintains it in a reactive state.
14
+ * The service is initialized with pre-loaded category data.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { CategoryService, CategoryServiceDefinition } from '@wix/stores/services';
19
+ * import { useService } from '@wix/services-manager-react';
20
+ *
21
+ * function CategoryComponent({ categoryConfig }) {
22
+ * return (
23
+ * <ServiceProvider services={createServicesMap([
24
+ * [CategoryServiceDefinition, CategoryService.withConfig(categoryConfig)]
25
+ * ])}>
26
+ * <CategoryDisplay />
27
+ * </ServiceProvider>
28
+ * );
29
+ * }
30
+ *
31
+ * function CategoryDisplay() {
32
+ * const categoryService = useService(CategoryServiceDefinition);
33
+ * const category = categoryService.category.get();
34
+ *
35
+ * return (
36
+ * <div>
37
+ * <h1>{category.name}</h1>
38
+ * <p>{category.description}</p>
39
+ * </div>
40
+ * );
41
+ * }
42
+ * ```
43
+ */
5
44
  export const CategoryService = implementService.withConfig()(CategoryServiceDefinition, ({ getService, config }) => {
6
45
  const signalsService = getService(SignalsServiceDefinition);
7
- const selectedCategory = signalsService.signal((config?.initialCategoryId || null));
8
- const categories = signalsService.signal(config?.categories);
9
- const loadCategories = async () => {
10
- const { categories: loadedCategories } = await loadCategoriesConfig();
11
- categories.set(loadedCategories);
12
- };
13
- // Track if this is the initial load to prevent navigation on service creation
14
- let isInitialLoad = true;
15
- const setSelectedCategory = (categoryId) => {
16
- selectedCategory.set(categoryId);
17
- };
18
- // Subscribe to category changes and handle navigation as a side effect
19
- signalsService.effect(() => {
20
- const categoryId = selectedCategory.get();
21
- // Skip navigation on initial load (when service is first created)
22
- if (isInitialLoad) {
23
- isInitialLoad = false;
24
- return;
25
- }
26
- // If a navigation handler is provided, use it
27
- if (config?.onCategoryChange) {
28
- const category = categoryId
29
- ? config?.categories.find((cat) => cat._id === categoryId) || null
30
- : null;
31
- config.onCategoryChange(categoryId, category);
32
- }
33
- });
46
+ const categorySignal = signalsService.signal(config.category);
34
47
  return {
35
- selectedCategory,
36
- categories,
37
- setSelectedCategory,
38
- loadCategories,
48
+ category: categorySignal,
39
49
  };
40
50
  });
41
51
  /**
42
- * Loads categories configuration from the Wix Categories API for SSR initialization.
52
+ * Loads category service configuration from the Wix Categories API for SSR initialization.
43
53
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
44
- * initial categories data that will be passed to the Category.Root component.
45
- * Fetches all visible categories and sorts them with "all-products" category first.
54
+ * a specific category by slug that will be used to configure the CategoryService.
46
55
  *
47
- * @returns Promise that resolves to an object containing categories array
56
+ * @param {string} slug - The category slug to load
57
+ * @returns {Promise} Promise that resolves to either success with config or not-found result
48
58
  *
49
59
  * @example
50
60
  * ```astro
51
61
  * ---
52
- * // Astro page example - pages/categories.astro
53
- * import { loadCategoriesConfig } from '@wix/stores/services';
62
+ * // Astro page example - pages/category/[slug].astro
63
+ * import { loadCategoryServiceConfig } from '@wix/stores/services';
54
64
  * import { Category } from '@wix/stores/components';
55
65
  *
56
- * // Load categories data during SSR
57
- * const categoryConfig = await loadCategoriesConfig();
66
+ * // Get category slug from URL params
67
+ * const { slug } = Astro.params;
68
+ *
69
+ * // Load category data during SSR
70
+ * const categoryResult = await loadCategoryServiceConfig(slug);
71
+ *
72
+ * // Handle not found case
73
+ * if (categoryResult.type === 'not-found') {
74
+ * return Astro.redirect('/404');
75
+ * }
58
76
  * ---
59
77
  *
60
- * <Category.Root categoryConfig={categoryConfig}>
61
- * <Category.List>
62
- * {({ categories, selectedCategory, setSelectedCategory }) => (
63
- * <nav className="category-nav">
64
- * <h2>Shop by Category</h2>
65
- * {categories.map(category => (
66
- * <button
67
- * key={category.id}
68
- * onClick={() => setSelectedCategory(category.id)}
69
- * className={selectedCategory === category.id ? 'active' : ''}
70
- * >
71
- * {category.name}
72
- * </button>
73
- * ))}
74
- * </nav>
75
- * )}
76
- * </Category.List>
78
+ * <Category.Root categoryConfig={categoryResult.config}>
79
+ * <Category.Name>
80
+ * {({ name }) => <h1>{name}</h1>}
81
+ * </Category.Name>
77
82
  * </Category.Root>
78
83
  * ```
79
84
  *
80
85
  * @example
81
86
  * ```tsx
82
- * // Next.js page example - pages/categories.tsx
87
+ * // Next.js page example - pages/category/[slug].tsx
83
88
  * import { GetServerSideProps } from 'next';
84
- * import { loadCategoriesConfig } from '@wix/stores/services';
89
+ * import { loadCategoryServiceConfig } from '@wix/stores/services';
85
90
  * import { Category } from '@wix/stores/components';
86
91
  *
87
92
  * interface CategoryPageProps {
88
- * categoryConfig: Awaited<ReturnType<typeof loadCategoriesConfig>>;
93
+ * categoryConfig: Awaited<ReturnType<typeof loadCategoryServiceConfig>>['config'];
89
94
  * }
90
95
  *
91
- * export const getServerSideProps: GetServerSideProps<CategoryPageProps> = async () => {
92
- * // Load categories data during SSR
93
- * const categoryConfig = await loadCategoriesConfig();
96
+ * export const getServerSideProps: GetServerSideProps<CategoryPageProps> = async ({ params }) => {
97
+ * const slug = params?.slug as string;
98
+ *
99
+ * // Load category data during SSR
100
+ * const categoryResult = await loadCategoryServiceConfig(slug);
101
+ *
102
+ * // Handle not found case
103
+ * if (categoryResult.type === 'not-found') {
104
+ * return {
105
+ * notFound: true,
106
+ * };
107
+ * }
94
108
  *
95
109
  * return {
96
110
  * props: {
97
- * categoryConfig,
111
+ * categoryConfig: categoryResult.config,
98
112
  * },
99
113
  * };
100
114
  * };
101
115
  *
102
116
  * export default function CategoryPage({ categoryConfig }: CategoryPageProps) {
103
117
  * return (
104
- * <div>
105
- * <h1>Product Categories</h1>
106
- * <Category.Root categoryConfig={categoryConfig}>
107
- * <Category.List>
108
- * {({ categories, selectedCategory, setSelectedCategory }) => (
109
- * <nav className="category-nav">
110
- * {categories.map(category => (
111
- * <button
112
- * key={category.id}
113
- * onClick={() => setSelectedCategory(category.id)}
114
- * className={`category-btn ${selectedCategory === category.id ? 'active' : ''}`}
115
- * >
116
- * {category.name}
117
- * </button>
118
- * ))}
119
- * </nav>
120
- * )}
121
- * </Category.List>
122
- * </Category.Root>
123
- * </div>
118
+ * <Category.Root categoryConfig={categoryConfig}>
119
+ * <Category.Name>
120
+ * {({ name }) => <h1>{name}</h1>}
121
+ * </Category.Name>
122
+ * </Category.Root>
124
123
  * );
125
124
  * }
126
125
  * ```
127
126
  */
128
- export async function loadCategoriesConfig() {
129
- try {
130
- const categoriesResponse = await categories
131
- .queryCategories({
132
- treeReference: {
133
- appNamespace: "@wix/stores",
134
- treeKey: null,
135
- },
136
- })
137
- .eq("visible", true)
138
- .find();
139
- const fetchedCategories = categoriesResponse.items || [];
140
- // Sort categories to put "all-products" first, keep the rest in original order
141
- const allProductsCategory = fetchedCategories.find((cat) => cat.slug === "all-products");
142
- const otherCategories = fetchedCategories.filter((cat) => cat.slug !== "all-products");
143
- const allCategories = allProductsCategory
144
- ? [allProductsCategory, ...otherCategories]
145
- : fetchedCategories;
146
- return {
147
- categories: allCategories,
148
- };
149
- }
150
- catch (error) {
151
- console.warn("Failed to load categories:", error);
127
+ export async function loadCategoryServiceConfig(slug) {
128
+ const category = await categories
129
+ .queryCategories({
130
+ treeReference: {
131
+ appNamespace: "@wix/stores",
132
+ },
133
+ })
134
+ .eq("slug", slug)
135
+ .find();
136
+ if (category.items.length === 0) {
152
137
  return {
153
- categories: [],
138
+ type: "not-found",
154
139
  };
155
140
  }
141
+ return {
142
+ type: "success",
143
+ config: {
144
+ category: category.items[0],
145
+ },
146
+ };
156
147
  }
@@ -1,10 +1,9 @@
1
- export { CatalogService, CatalogServiceDefinition, } from "./catalog-service.js";
2
- export { CategoryService, CategoryServiceDefinition, loadCategoriesConfig, } from "./category-service.js";
3
- export { CollectionService, CollectionServiceDefinition, loadCollectionServiceConfig, } from "./collection-service.js";
4
- export { FilterService, FilterServiceDefinition, Filter, AvailableOptions, } from "./filter-service.js";
1
+ export { CategoryService, CategoryServiceDefinition, loadCategoryServiceConfig, CategoryServiceConfig, } from "./category-service.js";
2
+ export { CategoriesListService, CategoriesListServiceDefinition, loadCategoriesListServiceConfig, CategoriesListServiceConfig, } from "./categories-list-service.js";
5
3
  export { ProductModifiersService, ProductModifiersServiceDefinition, } from "./product-modifiers-service.js";
6
4
  export { ProductService, ProductServiceDefinition, loadProductServiceConfig, } from "./product-service.js";
7
- export { RelatedProductsService, RelatedProductsServiceDefinition, loadRelatedProductsServiceConfig, } from "./related-products-service.js";
8
5
  export { SelectedVariantService, SelectedVariantServiceDefinition, } from "./selected-variant-service.js";
9
- export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, } from "./products-list-service.js";
10
- export { SortService, SortServiceDefinition, SortBy } from "./sort-service.js";
6
+ export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, ProductsListServiceConfig, } from "./products-list-service.js";
7
+ export { SortType, ProductsListSortService, ProductsListSortServiceDefinition, } from "./products-list-sort-service.js";
8
+ export { InventoryStatusType, ProductsListFiltersService, ProductsListFiltersServiceDefinition, loadProductsListFiltersServiceConfig, ProductsListFiltersServiceConfig, } from "./products-list-filters-service.js";
9
+ export { ProductsListPaginationService, ProductsListPaginationServiceDefinition, } from "./products-list-pagination-service.js";