@propeller-commerce/propeller-v2-react-ui 0.16.0 → 0.18.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 CHANGED
@@ -8,6 +8,67 @@ 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.18.0] - 2026-08-20
12
+
13
+ ### Added
14
+
15
+ - **After-hooks now say WHAT happened, not just that something did.** Three
16
+ callbacks reported success with no argument, which made them unusable for
17
+ anything that has to distinguish the outcome — analytics, audit trails, or
18
+ optimistic UI. All three arguments are optional, so existing zero-argument
19
+ callbacks keep working unchanged.
20
+ - `AddToFavorite.onFavoriteChanged(change?)` — `{ action: 'added' | 'removed',
21
+ listId, productId, clusterId }`. It fired identically for an add and a
22
+ removal, so a host could not report "added to wishlist" without inventing
23
+ the direction, and a wishlist metric that also counts removals is worse
24
+ than no metric.
25
+ - `FavoriteLists.onListChanged(change?)` / `useFavorites` — `{ action:
26
+ 'created' | 'updated' | 'deleted', listId, name, isDefault }`. Note the
27
+ existing `onCreate` / `onEdit` / `onDelete` props are *overrides* that
28
+ replace the default mutation, so they were never usable as notifications.
29
+ - `QuickOrder.onTemplateDownload()` — the template link was a bare `<a>`, so
30
+ a buyer fetching the spreadsheet left no trace. Navigation is untouched.
31
+
32
+ ### Notes
33
+
34
+ - `QuoteActions` deliberately gains no `afterReject`: the component has no
35
+ reject action to hook — only accept. A rejection callback would be dead API.
36
+ - `PurchaseAuthorizationRequests` needs no new prop either; the existing
37
+ `afterDeleteRequest` already covers the manager rejecting a request, which is
38
+ what "delete" means in that UI.
39
+
40
+ ## [0.17.0] - 2026-08-20
41
+
42
+ ### Fixed
43
+
44
+ - **A host `className` override could not beat the component's own utility
45
+ (PWP-942 #17).** Class lists were built by string-appending the override
46
+ after the package's defaults, which decides nothing — the cascade does, not
47
+ attribute order. `iconClassName="text-cocoa"` on `AccountIconAndMenu` (baked-in
48
+ `text-white`) produced an element carrying both and rendered white, while the
49
+ same override on `CartIconAndSidebar` appeared to work only because its
50
+ default happened to lose anyway. Every override site now merges through
51
+ `tailwind-merge`, so a conflicting utility is replaced rather than raced.
52
+ 59 sites across 47 components; BEM hooks and non-conflicting utilities are
53
+ untouched.
54
+
55
+ - **Anonymous catalog listings were scoped differently on the client than on
56
+ the server (PWP-942 #22).** Listing hooks derived `userId` only from a
57
+ logged-in user and omitted the key entirely for guests, while a server-side
58
+ seed scopes anonymous queries to the channel's `anonymousUserId`. The two
59
+ therefore asked different questions, and the client refetch quietly replaced
60
+ a correctly-scoped product list with a differently-scoped one — assortment
61
+ rules, negative order lists in particular, are applied per user. All five
62
+ listing hooks (`useProductSearch` ×2, `useProductSlider`, `useQuickOrder`,
63
+ `useSpareParts`) now resolve the id through one shared helper. Hosts that
64
+ supply no `anonymousUserId` behave exactly as before.
65
+
66
+ ### Added
67
+
68
+ - **`configuration.anonymousUserId`** — the channel's guest account, resolved
69
+ server-side and handed to the package so client-side listings can scope to
70
+ it. Same route `baseCategoryId` takes since PWP-913; no module guesses it.
71
+
11
72
  ## [0.16.0] - 2026-08-12
12
73
 
13
74
  ### Fixed
package/README.md CHANGED
@@ -307,9 +307,17 @@ and pass it once.
307
307
  | `language` | `string` | Locale code used to resolve localized content (e.g. `'NL'`, `'EN'`). |
308
308
  | `includeTax` | `boolean` | Whether displayed prices include tax. |
309
309
  | `currency` | `string` | Currency symbol for price formatting. Default: `'€'`. |
310
- | `configuration` | `unknown` | Free-form config bag forwarded to components — stuff your own settings in. |
310
+ | `configuration` | `unknown` | Config bag forwarded to components. Recognized keys: `baseCategoryId`, `anonymousUserId` (see below), image filters — plus anything of your own. |
311
311
  | `portalMode` | `string` | Storefront mode (e.g. `'open'`, `'closed'`). |
312
312
 
313
+ **`configuration.anonymousUserId`** — the channel's guest account. Listing
314
+ hooks scope logged-out catalog queries to it, so the client asks the same
315
+ question your server-rendered seed did. Resolve it server-side (only the
316
+ server can reach the channel) and pass it in; when it's absent, anonymous
317
+ queries send no `userId` and the backend falls back to the api key's own
318
+ scope. Getting this wrong is invisible — the grid renders, just with the
319
+ wrong assortment.
320
+
313
321
  The `value` object is reactive — when your auth/company/language state
314
322
  changes, recompute it (memoize on those dependencies) and the provider
315
323
  propagates the new value. Components re-render with fresh infra; service
@@ -584,15 +592,19 @@ cascade order — no `!important` needed:
584
592
  .propeller-breadcrumbs__separator { display: none; }
585
593
  ```
586
594
 
587
- **3. Per-instance `className`** — every component appends `props.className`
588
- on its root, so a one-off override is a regular prop:
595
+ **3. Per-instance `className`** — every component merges `props.className`
596
+ into its root classes, so a one-off override is a regular prop:
589
597
 
590
598
  ```tsx
591
599
  <ProductCard product={p} className="ring-2 ring-yellow-400" />
592
600
  ```
593
601
 
594
- `className` **adds to** the base classes — it doesn't replace them. To strip
595
- a default, use a BEM hook.
602
+ The merge runs through [`tailwind-merge`](https://github.com/dcastil/tailwind-merge)
603
+ (since 0.17.0), so an override **replaces** the base utility it conflicts with
604
+ rather than racing it in the cascade — `iconClassName="text-cocoa"` on a
605
+ component whose default is `text-white` now renders cocoa. Non-conflicting
606
+ utilities and the BEM hooks are left untouched. To remove a default outright
607
+ (rather than override it), use a BEM hook.
596
608
 
597
609
  See [STYLING.md](./STYLING.md) for the full token list, the complete BEM
598
610
  hook catalog, and the cascade rationale.