@reblu/site-blocks 0.9.0 → 0.11.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 +14 -0
- package/README.md +104 -1
- package/dist/index.cjs +475 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -11
- package/dist/index.d.ts +78 -11
- package/dist/index.js +472 -202
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @reblu/site-blocks
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c147a33: Add `ProductTrustItems` (REB-862): a plug-and-play Server Component that renders the store-wide trust messages from `ShopConfig.productTrustItems` (REB-858). Renders nothing when there is no data, skips items with an unknown icon or empty text, and never invents default claims. Ships `DEFAULT_TRUST_ICONS` (Lucide icons, bundled — no `lucide-react` needed in the SITE) with a per-icon `icons` override.
|
|
8
|
+
|
|
9
|
+
## 0.10.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- e78229a: REB-853 — rename the `Specialty` organism to the niche-agnostic `ParentPage` (a page with a linked grid of child pages), with props `childPages`, `childPageHref` and `childPagesLabel`.
|
|
14
|
+
|
|
15
|
+
`Specialty` / `SpecialtyProps` and the props `treatments`, `treatmentHref` and `treatmentsLabel` remain as `@deprecated` aliases — `Specialty` is the same reference as `ParentPage`, so rendering is unchanged. They will be removed in the next major, not before 2027-03-31.
|
|
16
|
+
|
|
3
17
|
## 0.9.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -15,10 +15,11 @@ a different-looking site for every tenant, with zero forks.
|
|
|
15
15
|
| `readingTime`, `formatPrice`, `buildShareUrls`, `markdownToSafeHtml` | `.` | Pure, framework-agnostic helpers (RSC-safe). |
|
|
16
16
|
| `sanitizeHtml` | `.` | Sanitises an HTML string before `dangerouslySetInnerHTML` — the **HTML boundary**. See "Security boundaries" below. |
|
|
17
17
|
| `MarkdownRenderer` | `.` | Canonical Blog renderer: `marked` → **hast-util-sanitize** (XSS) → component map, with a YouTube-domain allowlist. RSC-safe. |
|
|
18
|
-
| `Treatment`, `
|
|
18
|
+
| `Treatment`, `ParentPage`, `ProfileCard`, `ProductCard` | `.` | Presentational organisms over the SITE API contracts. RSC-safe. `Specialty`: deprecated alias, see below. |
|
|
19
19
|
| `ShopFilters` | `.` | Plug-and-play shop filter chrome over `GET /api/site/shop/facets`. RSC-safe. See "Shop filters" below. |
|
|
20
20
|
| `CartLineList`, `CartSummary`, `AddedToCartToast`, `CheckoutLoginPrompt`, `CheckoutForm`, `OrderConfirmation` | `.` | Cart & checkout organisms. RSC-safe by construction. See "Cart & checkout" below. |
|
|
21
21
|
| `PageBlocks`, `FaqAccordion` | `.` | Registry-block renderer (`PageDetail.blocks`) and native `<details>` FAQ. Server Components. See "Page blocks" below. |
|
|
22
|
+
| `ProductTrustItems`, `DEFAULT_TRUST_ICONS` | `.` | Store-wide trust messages from `ShopConfig.productTrustItems`. Server Component. See "Product trust items" below. |
|
|
22
23
|
| `buildFaqPageJsonLd`, `collectFaqItems` | `./seo` | schema.org `FAQPage` structured data. Directive-free (also on `.`). See "Page blocks" below. |
|
|
23
24
|
| `useCollection` | `./client` | Headless filterable/sortable/paginated collection hook (facets, category, tag, search). Serves both page and blog indexes. |
|
|
24
25
|
| `Collection` | `./client` | Token-driven presentational grid over `useCollection`. |
|
|
@@ -380,6 +381,108 @@ Every title/description is overridable via `labels` (see
|
|
|
380
381
|
"`useShopOrderStatus` — the order-confirmation flow" for the full wiring
|
|
381
382
|
recipe.
|
|
382
383
|
|
|
384
|
+
## Product trust items
|
|
385
|
+
|
|
386
|
+
`ProductTrustItems` renders the store-wide trust messages (shipping, returns,
|
|
387
|
+
secure payment…) the owner configures in nexus and the API serves as
|
|
388
|
+
`ShopConfig.productTrustItems` (REB-858). It is a Server Component — no
|
|
389
|
+
`'use client'`, no hooks — so it works in a Server Component page and inside a
|
|
390
|
+
Client Component alike. Drop it under the add-to-cart button:
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
import { createRebluClient } from '@reblu/site-client'
|
|
394
|
+
import { ProductTrustItems } from '@reblu/site-blocks'
|
|
395
|
+
|
|
396
|
+
const client = createRebluClient({
|
|
397
|
+
baseUrl: 'https://api.reblu.app',
|
|
398
|
+
apiKey: process.env.REBLU_API_KEY!,
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
export default async function ProductPage() {
|
|
402
|
+
const shopConfig = await client.shop.config()
|
|
403
|
+
return (
|
|
404
|
+
<>
|
|
405
|
+
{/* …product, price, add-to-cart… */}
|
|
406
|
+
<ProductTrustItems items={shopConfig.productTrustItems} className='border-t pt-4' />
|
|
407
|
+
</>
|
|
408
|
+
)
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Semantics — the API is the only source of claims
|
|
413
|
+
|
|
414
|
+
- **No data, no block.** `null`, `undefined` or `[]` render nothing. The
|
|
415
|
+
component never invents default items.
|
|
416
|
+
- **Unknown icons are skipped**, with no fallback icon. The contract is
|
|
417
|
+
forward-compatible (`icon: ShopProductTrustIcon | (string & {})`), so a newer
|
|
418
|
+
API may send an icon this version does not know; that item is dropped.
|
|
419
|
+
- **Empty text is skipped** (whitespace-only included). If no item survives,
|
|
420
|
+
nothing is rendered — never an empty `<ul>`.
|
|
421
|
+
- **Unknown item keys are ignored.**
|
|
422
|
+
- Order is the configured order.
|
|
423
|
+
|
|
424
|
+
### Markup and styling
|
|
425
|
+
|
|
426
|
+
A semantic `<ul>` (or `<ol>` via `as='ol'`) of `<li>` rows; each icon is
|
|
427
|
+
`aria-hidden` because the text carries the meaning. Colours come from theme
|
|
428
|
+
tokens only (`text-muted-foreground`, `text-foreground/60`). `className` styles
|
|
429
|
+
the list, `itemClassName` each row.
|
|
430
|
+
|
|
431
|
+
### Overriding icons
|
|
432
|
+
|
|
433
|
+
`DEFAULT_TRUST_ICONS` maps every `ShopProductTrustIcon` to a Lucide icon
|
|
434
|
+
(`shipping`→Truck, `returns`→RotateCcw, `secure-payment`→ShieldCheck,
|
|
435
|
+
`support`→Headset, `gift`→Gift, `pickup`→Store, `warranty`→BadgeCheck,
|
|
436
|
+
`quality`→Award). They are bundled into this package, so the SITE needs no
|
|
437
|
+
`lucide-react` of its own. Pass `icons` to replace any of them — the override is
|
|
438
|
+
merged over the defaults and receives `className` and `aria-hidden`:
|
|
439
|
+
|
|
440
|
+
```tsx
|
|
441
|
+
import { Truck } from 'my-icon-set'
|
|
442
|
+
|
|
443
|
+
<ProductTrustItems items={shopConfig.productTrustItems} icons={{ shipping: Truck }} />
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`icons` cannot add a new icon key: an item whose `icon` this version does not
|
|
447
|
+
know is still skipped.
|
|
448
|
+
|
|
449
|
+
## `ParentPage` (formerly `Specialty`)
|
|
450
|
+
|
|
451
|
+
`ParentPage` renders a page that groups other pages: the hero and content
|
|
452
|
+
sections of a `PageDetail`, then an optional linked grid of its child pages
|
|
453
|
+
(`PageListItem[]` — cover image, title, excerpt).
|
|
454
|
+
|
|
455
|
+
```tsx
|
|
456
|
+
import { ParentPage } from '@reblu/site-blocks'
|
|
457
|
+
|
|
458
|
+
export function ServicesHub({ page, services }) {
|
|
459
|
+
return (
|
|
460
|
+
<ParentPage
|
|
461
|
+
page={page}
|
|
462
|
+
childPages={services}
|
|
463
|
+
childPageHref={(slug) => `/services/${slug}`}
|
|
464
|
+
childPagesLabel='Services'
|
|
465
|
+
/>
|
|
466
|
+
)
|
|
467
|
+
}
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**Deprecated (REB-853) — removed in the next major, not before 2027-03-31:**
|
|
471
|
+
|
|
472
|
+
| Deprecated | Use instead |
|
|
473
|
+
| ----------------- | ----------------- |
|
|
474
|
+
| `Specialty` | `ParentPage` |
|
|
475
|
+
| `SpecialtyProps` | `ParentPageProps` |
|
|
476
|
+
| `treatments` | `childPages` |
|
|
477
|
+
| `treatmentHref` | `childPageHref` |
|
|
478
|
+
| `treatmentsLabel` | `childPagesLabel` |
|
|
479
|
+
|
|
480
|
+
`Specialty` is the same component reference as `ParentPage`, not a copy, so
|
|
481
|
+
existing code renders exactly as before. When a new prop and its deprecated
|
|
482
|
+
counterpart are both passed, the new one wins. The default grid heading stays
|
|
483
|
+
`"Treatments"` and the root keeps `data-slot="specialty"` until that major, so
|
|
484
|
+
the rename changes no markup — pass `childPagesLabel` to set your own heading.
|
|
485
|
+
|
|
383
486
|
## Page blocks
|
|
384
487
|
|
|
385
488
|
`PageBlocks` renders a page's registry blocks (`PageDetail.blocks` from
|