@propeller-commerce/propeller-v2-react-ui 0.11.4 → 0.12.0
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.
- package/CHANGELOG.md +24 -0
- package/dist/index.cjs +19 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,30 @@ once it reaches 1.0. Until then (the `0.x` line) the public API may change
|
|
|
8
8
|
between minor versions; breaking changes are called out below and in
|
|
9
9
|
[MIGRATION.md](./MIGRATION.md).
|
|
10
10
|
|
|
11
|
+
## [0.12.0] - 2026-07-31
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`productTrackAttributes` on `<ProductGrid>`, `<SearchBar>` and
|
|
16
|
+
`useProductSearch`.** Pass the attribute names a card renders — e.g.
|
|
17
|
+
`productTrackAttributes={['MPN']}` — and they arrive on
|
|
18
|
+
`product.attributes` for every item in the result, ready to read from a
|
|
19
|
+
card slot like `belowName`. `useProductInfo` has had an option of this name
|
|
20
|
+
since the PDP work; the grid side simply never forwarded one, so hosts that
|
|
21
|
+
set it in their portal config saw it silently ignored on listings and had
|
|
22
|
+
to fetch attributes themselves in a second request.
|
|
23
|
+
|
|
24
|
+
Requires `propeller-sdk-v2` >= 0.16.0, where the `category` and `products`
|
|
25
|
+
operations gained `$attributeResultSearchInput` and `ProductGridFields`
|
|
26
|
+
gained the matching `attributes(input:)` selection.
|
|
27
|
+
|
|
28
|
+
Naming the attributes you render is not just a payload optimisation — it is
|
|
29
|
+
the correct behaviour. With no input the server returns the *first page* of
|
|
30
|
+
a product's attributes (12 per product), so on a product carrying more than
|
|
31
|
+
12 the ones on later pages are missing with no error. Filtering to the names
|
|
32
|
+
you need also cut a 24-product category response from ~168 KB to ~124 KB in
|
|
33
|
+
our testing.
|
|
34
|
+
|
|
11
35
|
## [0.11.4] - 2026-07-31
|
|
12
36
|
|
|
13
37
|
### Fixed
|
package/dist/index.cjs
CHANGED
|
@@ -2090,7 +2090,7 @@ function useProductInfo(options) {
|
|
|
2090
2090
|
if (options.user && "customerId" in options.user) input.customerId = options.user.customerId;
|
|
2091
2091
|
return input;
|
|
2092
2092
|
}
|
|
2093
|
-
function
|
|
2093
|
+
function buildAttributeInput2() {
|
|
2094
2094
|
const names = options.productTrackAttributes;
|
|
2095
2095
|
if (!names || names.length === 0) return void 0;
|
|
2096
2096
|
return { attributeDescription: { names } };
|
|
@@ -2113,7 +2113,7 @@ function useProductInfo(options) {
|
|
|
2113
2113
|
orderlistIds = (orderlists?.items ?? []).map((ol) => ol.id);
|
|
2114
2114
|
}
|
|
2115
2115
|
const service = propellerV2CoreUi.createServices(graphqlClient).product;
|
|
2116
|
-
const attributeInput =
|
|
2116
|
+
const attributeInput = buildAttributeInput2();
|
|
2117
2117
|
const variables = {
|
|
2118
2118
|
productId,
|
|
2119
2119
|
language,
|
|
@@ -2203,6 +2203,10 @@ function useProductInfo(options) {
|
|
|
2203
2203
|
};
|
|
2204
2204
|
}
|
|
2205
2205
|
var inflightFetches2 = /* @__PURE__ */ new Set();
|
|
2206
|
+
function buildAttributeInput(names) {
|
|
2207
|
+
if (!names || names.length === 0) return void 0;
|
|
2208
|
+
return { attributeDescription: { names } };
|
|
2209
|
+
}
|
|
2206
2210
|
function useProductSearch(options) {
|
|
2207
2211
|
const { graphqlClient, configuration } = options;
|
|
2208
2212
|
const isControlled = options.products !== void 0;
|
|
@@ -2335,6 +2339,7 @@ function useProductSearch(options) {
|
|
|
2335
2339
|
const filterAvailableAttributeInput = {
|
|
2336
2340
|
isSearchable: true
|
|
2337
2341
|
};
|
|
2342
|
+
const attributeInput = buildAttributeInput(options.productTrackAttributes);
|
|
2338
2343
|
const variables = {
|
|
2339
2344
|
categoryId: catId,
|
|
2340
2345
|
language: lang,
|
|
@@ -2342,7 +2347,8 @@ function useProductSearch(options) {
|
|
|
2342
2347
|
priceCalculateProductInput,
|
|
2343
2348
|
filterAvailableAttributeInput,
|
|
2344
2349
|
imageSearchFilters: configuration?.imageSearchFiltersGrid,
|
|
2345
|
-
imageVariantFilters: configuration?.imageVariantFiltersMedium
|
|
2350
|
+
imageVariantFilters: configuration?.imageVariantFiltersMedium,
|
|
2351
|
+
...attributeInput && { attributeResultSearchInput: attributeInput }
|
|
2346
2352
|
};
|
|
2347
2353
|
const response = await service.getCategory(variables);
|
|
2348
2354
|
if (thisId !== fetchIdRef.current) return;
|
|
@@ -2403,7 +2409,9 @@ function useProductSearch(options) {
|
|
|
2403
2409
|
taxZone,
|
|
2404
2410
|
pageSize,
|
|
2405
2411
|
pagination.currentPage,
|
|
2406
|
-
configuration
|
|
2412
|
+
configuration,
|
|
2413
|
+
// Stringified: callers pass an array literal, so identity changes each render.
|
|
2414
|
+
JSON.stringify(options.productTrackAttributes ?? [])
|
|
2407
2415
|
]);
|
|
2408
2416
|
const search = React6.useCallback(
|
|
2409
2417
|
(term) => {
|
|
@@ -2482,13 +2490,15 @@ function useProductSearch(options) {
|
|
|
2482
2490
|
...contactId !== void 0 && { contactId },
|
|
2483
2491
|
...customerId !== void 0 && { customerId }
|
|
2484
2492
|
};
|
|
2493
|
+
const attributeInput = buildAttributeInput(options.productTrackAttributes);
|
|
2485
2494
|
const variables = {
|
|
2486
2495
|
categoryId: catId,
|
|
2487
2496
|
language,
|
|
2488
2497
|
categoryProductSearchInput,
|
|
2489
2498
|
priceCalculateProductInput,
|
|
2490
2499
|
imageSearchFilters: configuration?.imageSearchFiltersGrid,
|
|
2491
|
-
imageVariantFilters: configuration?.imageVariantFiltersMedium
|
|
2500
|
+
imageVariantFilters: configuration?.imageVariantFiltersMedium,
|
|
2501
|
+
...attributeInput && { attributeResultSearchInput: attributeInput }
|
|
2492
2502
|
};
|
|
2493
2503
|
const response = await service.getCategory(variables);
|
|
2494
2504
|
const productsResponse = response?.products;
|
|
@@ -2507,7 +2517,7 @@ function useProductSearch(options) {
|
|
|
2507
2517
|
}, 300);
|
|
2508
2518
|
},
|
|
2509
2519
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2510
|
-
[graphqlClient, language, configuration, userKey, JSON.stringify(options.orderlistIds ?? []), options.applyOrderlists]
|
|
2520
|
+
[graphqlClient, language, configuration, userKey, JSON.stringify(options.orderlistIds ?? []), options.applyOrderlists, JSON.stringify(options.productTrackAttributes ?? [])]
|
|
2511
2521
|
);
|
|
2512
2522
|
React6.useEffect(() => {
|
|
2513
2523
|
if (!isControlled) fetchProducts();
|
|
@@ -9034,6 +9044,7 @@ function ProductGrid(rawProps) {
|
|
|
9034
9044
|
brand: props.brand,
|
|
9035
9045
|
orderlistIds: props.orderlistIds,
|
|
9036
9046
|
applyOrderlists: props.applyOrderlists,
|
|
9047
|
+
productTrackAttributes: props.productTrackAttributes,
|
|
9037
9048
|
language: props.language,
|
|
9038
9049
|
taxZone: props.taxZone,
|
|
9039
9050
|
user: props.user,
|
|
@@ -18396,7 +18407,8 @@ function SearchBar(rawProps) {
|
|
|
18396
18407
|
user: props.user,
|
|
18397
18408
|
companyId: props.companyId,
|
|
18398
18409
|
orderlistIds: props.orderlistIds,
|
|
18399
|
-
applyOrderlists: props.applyOrderlists
|
|
18410
|
+
applyOrderlists: props.applyOrderlists,
|
|
18411
|
+
productTrackAttributes: props.productTrackAttributes
|
|
18400
18412
|
});
|
|
18401
18413
|
const results = searchResults.slice(0, maxResults).map((item) => mapToSearchBarResult(item, props.language));
|
|
18402
18414
|
const itemsFound = searchItemsFound;
|