@thorprovider/blocks 0.1.1 → 0.1.3
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/.turbo/turbo-build.log +15 -15
- package/.turbo/turbo-test.log +42 -5
- package/AGENTS.md +1 -1
- package/README.md +94 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts.d.mts +1266 -97
- package/dist/contracts.d.ts +1266 -97
- package/dist/contracts.js +225 -9
- package/dist/contracts.js.map +1 -1
- package/dist/contracts.mjs +207 -10
- package/dist/contracts.mjs.map +1 -1
- package/dist/index.d.mts +756 -96
- package/dist/index.d.ts +756 -96
- package/dist/index.js +5114 -3702
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4939 -3551
- package/dist/index.mjs.map +1 -1
- package/docs/standards/theming.md +32 -5
- package/package.json +2 -2
- package/src/blocks/e-commerce/category-filters/category-filter-2-filter-panel.tsx +136 -93
- package/src/blocks/e-commerce/category-filters/category-filter-2.test.tsx +513 -0
- package/src/blocks/e-commerce/category-filters/category-filter-2.tsx +728 -148
- package/src/blocks/e-commerce/checkout-forms/checkout-confirmation-fulfilment-progress.tsx +14 -8
- package/src/blocks/e-commerce/checkout-forms/checkout-confirmation.test.tsx +136 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-confirmation.tsx +145 -99
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-order-summary.tsx +215 -102
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-payment-step.tsx +6 -2
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-shipping-step.tsx +51 -2
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx +216 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.tsx +114 -11
- package/src/blocks/e-commerce/navigation/back-to-top.test.tsx +27 -0
- package/src/blocks/e-commerce/navigation/back-to-top.tsx +71 -0
- package/src/blocks/e-commerce/navigation/breadcrumb.test.tsx +174 -0
- package/src/blocks/e-commerce/navigation/breadcrumb.tsx +130 -0
- package/src/blocks/e-commerce/navigation/mobile-bottom-nav.test.tsx +74 -0
- package/src/blocks/e-commerce/navigation/mobile-bottom-nav.tsx +78 -0
- package/src/blocks/e-commerce/navigation/mobile-category-drawer.test.tsx +42 -2
- package/src/blocks/e-commerce/navigation/mobile-category-drawer.tsx +10 -8
- package/src/blocks/e-commerce/navigation/skip-to-content.test.tsx +35 -0
- package/src/blocks/e-commerce/navigation/skip-to-content.tsx +37 -0
- package/src/blocks/e-commerce/product-categories/product-category-2.test.tsx +51 -0
- package/src/blocks/e-commerce/product-categories/product-category-2.tsx +56 -36
- package/src/blocks/e-commerce/product-list/product-card-1.test.tsx +88 -0
- package/src/blocks/e-commerce/product-list/product-card-1.tsx +141 -80
- package/src/blocks/e-commerce/product-list/product-showcase-1.test.tsx +78 -0
- package/src/blocks/e-commerce/product-list/product-showcase-1.tsx +277 -0
- package/src/blocks/e-commerce/product-overview/product-overview-1.test.tsx +182 -0
- package/src/blocks/e-commerce/product-overview/product-overview-1.tsx +298 -129
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.test.tsx +229 -0
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.tsx +313 -110
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.test.tsx +72 -0
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.tsx +20 -1
- package/src/blocks/marketing/footers/footer-section-1.test.tsx +117 -0
- package/src/blocks/marketing/footers/footer-section-1.tsx +46 -9
- package/src/blocks/marketing/navbars/navbar-4-account-menu.test.tsx +38 -0
- package/src/blocks/marketing/navbars/navbar-4-account-menu.tsx +30 -14
- package/src/blocks/marketing/navbars/navbar-4-cart-sheet.test.tsx +204 -0
- package/src/blocks/marketing/navbars/navbar-4-cart-sheet.tsx +144 -21
- package/src/blocks/marketing/navbars/navbar-4.test.tsx +233 -0
- package/src/blocks/marketing/navbars/navbar-4.tsx +235 -60
- package/src/index.ts +56 -0
- package/src/lib/cart.test.ts +15 -0
- package/src/lib/cart.ts +11 -0
- package/src/lib/contracts-curated.test.ts +207 -0
- package/src/lib/contracts-server-boundary.test.ts +52 -0
- package/src/lib/contracts.ts +234 -6
- package/src/lib/money.test.ts +64 -0
- package/src/lib/money.ts +65 -0
- package/tsup.config.ts +0 -1
- package/vitest.config.ts +9 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -6,19 +6,19 @@ CLI Target: esnext
|
|
|
6
6
|
CLI Cleaning output folder
|
|
7
7
|
CJS Build start
|
|
8
8
|
ESM Build start
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
ESM dist/contracts.mjs 11.75 KB
|
|
10
|
+
ESM dist/index.mjs 778.08 KB
|
|
11
|
+
ESM dist/contracts.mjs.map 29.49 KB
|
|
12
|
+
ESM dist/index.mjs.map 1.29 MB
|
|
13
|
+
ESM ⚡️ Build success in 228ms
|
|
14
|
+
CJS dist/contracts.js 16.83 KB
|
|
15
|
+
CJS dist/index.js 878.89 KB
|
|
16
|
+
CJS dist/contracts.js.map 29.69 KB
|
|
17
|
+
CJS dist/index.js.map 1.27 MB
|
|
18
|
+
CJS ⚡️ Build success in 229ms
|
|
19
19
|
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in
|
|
21
|
-
DTS dist/index.d.ts 86
|
|
22
|
-
DTS dist/contracts.d.ts
|
|
23
|
-
DTS dist/index.d.mts 86
|
|
24
|
-
DTS dist/contracts.d.mts
|
|
20
|
+
DTS ⚡️ Build success in 10197ms
|
|
21
|
+
DTS dist/index.d.ts 120.86 KB
|
|
22
|
+
DTS dist/contracts.d.ts 57.89 KB
|
|
23
|
+
DTS dist/index.d.mts 120.86 KB
|
|
24
|
+
DTS dist/contracts.d.mts 57.89 KB
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
|
|
2
2
|
RUN v3.2.4 /home/nelson/dev/active/thorprovider/repos/thorcommerce/packages/blocks
|
|
3
3
|
|
|
4
|
-
✓ src/blocks/e-commerce/
|
|
4
|
+
✓ src/blocks/e-commerce/navigation/mega-menu.test.tsx (9 tests) 1189ms
|
|
5
|
+
✓ MegaMenu > renders category columns from the categories prop 627ms
|
|
6
|
+
✓ src/blocks/e-commerce/navigation/mobile-category-drawer.test.tsx (12 tests) 1191ms
|
|
7
|
+
✓ MobileCategoryDrawer > keeps the drawer mounted off-screen with aria-hidden when closed 728ms
|
|
8
|
+
✓ src/blocks/e-commerce/product-categories/product-category-2.test.tsx (5 tests) 329ms
|
|
9
|
+
stderr | src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx > CheckoutForm1 payment step — launch flow collects no raw card data > renders card fields only in the explicit legacy mode
|
|
10
|
+
Received `true` for a non-boolean attribute `inline-end`.
|
|
5
11
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
If you want to write it to the DOM, pass a string instead: inline-end="true" or inline-end={value.toString()}.
|
|
13
|
+
|
|
14
|
+
✓ src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx (10 tests) 337ms
|
|
15
|
+
✓ src/blocks/e-commerce/checkout-forms/checkout-confirmation.test.tsx (7 tests) 567ms
|
|
16
|
+
✓ src/blocks/marketing/footers/footer-section-1.test.tsx (9 tests) 208ms
|
|
17
|
+
✓ src/blocks/e-commerce/shopping-carts/shopping-cart-4.test.tsx (17 tests) 704ms
|
|
18
|
+
✓ src/blocks/e-commerce/product-list/product-card-1.test.tsx (8 tests) 855ms
|
|
19
|
+
✓ src/blocks/marketing/navbars/navbar-4-cart-sheet.test.tsx (15 tests) 583ms
|
|
20
|
+
✓ Navbar4CartSheet — authoritative subtotal > never renders a fake zero for a supplied but absent/malformed subtotal 430ms
|
|
21
|
+
✓ src/blocks/e-commerce/navigation/skip-to-content.test.tsx (5 tests) 52ms
|
|
22
|
+
✓ src/blocks/marketing/navbars/navbar-4.test.tsx (19 tests) 851ms
|
|
23
|
+
✓ src/lib/money.test.ts (10 tests) 473ms
|
|
24
|
+
✓ formatMoney > uses the money currency rather than a hardcoded one 371ms
|
|
25
|
+
✓ src/lib/contracts-server-boundary.test.ts (3 tests) 92ms
|
|
26
|
+
✓ src/blocks/e-commerce/navigation/mobile-bottom-nav.test.tsx (7 tests) 446ms
|
|
27
|
+
✓ src/blocks/e-commerce/category-filters/category-filter-2.test.tsx (39 tests) 2736ms
|
|
28
|
+
✓ CategoryFilter2 — controlled canonical query > renders the query-selected search, category, sort and page values 428ms
|
|
29
|
+
✓ CategoryFilter2 — controlled canonical query > renders collection controls when collections are supplied 354ms
|
|
30
|
+
✓ CategoryFilter2 — no fabricated price or sort choices > omits the price control without a real backend range 301ms
|
|
31
|
+
✓ src/blocks/e-commerce/navigation/category-icon.test.tsx (7 tests) 584ms
|
|
32
|
+
✓ src/blocks/e-commerce/storefront-hero/storefront-hero-1.test.tsx (6 tests) 867ms
|
|
33
|
+
✓ StorefrontHero1 — optional editorial image > renders no editorial image when none is supplied 325ms
|
|
34
|
+
✓ src/lib/contracts.test.ts (3 tests) 33ms
|
|
35
|
+
✓ src/lib/cart.test.ts (2 tests) 23ms
|
|
36
|
+
✓ src/blocks/e-commerce/product-overview/product-overview-1.test.tsx (14 tests) 200ms
|
|
37
|
+
✓ src/blocks/e-commerce/navigation/breadcrumb.test.tsx (12 tests) 80ms
|
|
38
|
+
✓ src/blocks/e-commerce/navigation/back-to-top.test.tsx (5 tests) 23ms
|
|
39
|
+
✓ src/blocks/e-commerce/checkout-forms/card-formatting.test.ts (10 tests) 10ms
|
|
40
|
+
✓ src/lib/contracts-curated.test.ts (22 tests) 550ms
|
|
41
|
+
✓ src/blocks/e-commerce/product-list/product-showcase-1.test.tsx (7 tests) 498ms
|
|
42
|
+
|
|
43
|
+
Test Files 25 passed (25)
|
|
44
|
+
Tests 263 passed (263)
|
|
45
|
+
Start at 11:37:52
|
|
46
|
+
Duration 16.34s (transform 12.71s, setup 0ms, collect 81.98s, tests 13.48s, environment 33ms, prepare 18.67s)
|
|
10
47
|
|
package/AGENTS.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!-- BLOCKS-AGENTS-MD-START -->[@thorprovider/blocks Docs]|root: ./blocks|
|
|
1
|
+
<!-- BLOCKS-AGENTS-MD-START -->[@thorprovider/blocks Docs]|root: ./blocks|Electrostore MVP: see director roadmap.|To regenerate: yarn workspace @thorprovider/blocks generate:agent-index|.:{README.md}|docs/standards:{data-contracts.md,theming.md}<!-- BLOCKS-AGENTS-MD-END -->
|
package/README.md
CHANGED
|
@@ -60,6 +60,7 @@ Blocks follow `src/blocks/<category>/<section>/<block>.tsx`. Each block co-locat
|
|
|
60
60
|
| `ProductCard2` | E-commerce | Clean three-up grid with ratings |
|
|
61
61
|
| `ProductCard3` | E-commerce | Deals grid with badges, low-stock and wishlist |
|
|
62
62
|
| `ProductCard5` | E-commerce | Table-style comparison with sorting and filtering |
|
|
63
|
+
| `ProductShowcase1` | E-commerce | Combined grid-and-carousel of product cards with manual paging |
|
|
63
64
|
| `ProductOverview1` | E-commerce | Product detail with gallery, variants and add-to-cart |
|
|
64
65
|
| `ProductQuickView` | E-commerce | Quick-view dialog with gallery, variants and quantity |
|
|
65
66
|
| `ReviewRating1` | E-commerce | Review list with rating summary |
|
|
@@ -72,7 +73,7 @@ Blocks follow `src/blocks/<category>/<section>/<block>.tsx`. Each block co-locat
|
|
|
72
73
|
| `CategoryFilter2` | E-commerce | Filter sidebar with mobile sheet |
|
|
73
74
|
| `ShoppingCart1` | E-commerce | Detailed cart summary |
|
|
74
75
|
| `ShoppingCart2` | E-commerce | Cart with promo code and shipping |
|
|
75
|
-
| `ShoppingCart4` | E-commerce |
|
|
76
|
+
| `ShoppingCart4` | E-commerce | Cart review with backend-authoritative totals; `presentation` `compact` (collapsible card) or `page` (full-width review) |
|
|
76
77
|
| `CheckoutForm1` | E-commerce | Essential checkout fields |
|
|
77
78
|
| `CheckoutForm2` | E-commerce | Single-page checkout with order summary beside |
|
|
78
79
|
| `CheckoutConfirmation` | E-commerce | Order confirmation with fulfilment timeline |
|
|
@@ -91,6 +92,84 @@ Blocks follow `src/blocks/<category>/<section>/<block>.tsx`. Each block co-locat
|
|
|
91
92
|
|
|
92
93
|
Interactions are exposed as callbacks (e.g. `onAddToCart`, `onBuyNow`, `onSelectColor`). Elements stay in the DOM with no-op behavior when a callback is absent.
|
|
93
94
|
|
|
95
|
+
## Optional brand props
|
|
96
|
+
|
|
97
|
+
Three existing blocks expose an optional brand seam. Omitting the prop renders
|
|
98
|
+
the block's current output unchanged; no demo content is added.
|
|
99
|
+
|
|
100
|
+
- `Navbar4` — `logoAccent?: { text: string; className?: string }` accents a
|
|
101
|
+
trailing segment of `logoText`. With `logoText="ElectroCuba"` and
|
|
102
|
+
`logoAccent={{ text: 'Cuba', className: 'text-brand-promo' }}`, the block
|
|
103
|
+
renders `Electro` plus an accented `Cuba` span. If `text` is not a trailing
|
|
104
|
+
segment of `logoText`, the wordmark renders unchanged.
|
|
105
|
+
- `FooterSection1` — `brandAccent?: { text: string; className?: string }` applies
|
|
106
|
+
the same trailing-segment accent to `brandName`.
|
|
107
|
+
- `StorefrontHero1` — `heroImage?: { src: string; alt: string }` renders a native
|
|
108
|
+
`<img>` when `src` is a non-empty string, and nothing when the prop is absent
|
|
109
|
+
or `src` is blank (never an empty `src`). The product grid is unaffected.
|
|
110
|
+
|
|
111
|
+
`className` carries the consumer's own semantic token (e.g. `text-brand-promo`);
|
|
112
|
+
the library hardcodes no brand color.
|
|
113
|
+
|
|
114
|
+
## Custom surface `className`
|
|
115
|
+
|
|
116
|
+
`Navbar4` (outer `<header>`) and `FooterSection1` (outer `<footer>`) accept an
|
|
117
|
+
optional `className`, merged with the existing `cn` helper. It is purely
|
|
118
|
+
presentational: no layout, structure, or behavior prop, and no hardcoded color.
|
|
119
|
+
|
|
120
|
+
- **Omitted `className`** — the block renders its default surface unchanged.
|
|
121
|
+
`Navbar4` keeps `bg-background/95` **and** its
|
|
122
|
+
`supports-backdrop-filter:bg-background/80` variant; `FooterSection1` keeps
|
|
123
|
+
`bg-secondary`.
|
|
124
|
+
- **Supplied `className`** — the consumer owns the surface. The default
|
|
125
|
+
background **and its backdrop-filter variant** are not applied, so a semantic
|
|
126
|
+
surface such as `bg-brand-nav text-brand-nav-foreground` actually paints (the
|
|
127
|
+
`supports-backdrop-filter` variant would otherwise win on Chromium and mask
|
|
128
|
+
it). Layout, border, sticky, and `backdrop-blur-md` classes stay internal.
|
|
129
|
+
|
|
130
|
+
The consumer is responsible for the text, transparency, and context tokens of a
|
|
131
|
+
supplied surface. `Navbar4` adapts its primary nav links: they inherit the
|
|
132
|
+
surface text color and add `hover:text-foreground` so `hover:bg-muted` never
|
|
133
|
+
paints white-on-light. No magic colors are introduced by the block.
|
|
134
|
+
|
|
135
|
+
## Footer newsletter
|
|
136
|
+
|
|
137
|
+
`FooterSection1` renders the interactive newsletter form (input + submit button)
|
|
138
|
+
**only** when `newsletter.onSubmit` is supplied. A `newsletter` object without
|
|
139
|
+
`onSubmit` renders no form, input, or button — never a fake form. Omit
|
|
140
|
+
`newsletter` entirely to hide the newsletter block.
|
|
141
|
+
|
|
142
|
+
## Cart presentation (controlled)
|
|
143
|
+
|
|
144
|
+
The cart is presented in two shapes that share one data contract, so a change in
|
|
145
|
+
either is visible in the other.
|
|
146
|
+
|
|
147
|
+
- `ShoppingCart4` is the cart block. Its optional `presentation` prop selects
|
|
148
|
+
`'compact'` (default: a collapsible `max-w-md` card with an internal scroller —
|
|
149
|
+
the navbar lateral) or `'page'` (always expanded, full-width `max-w-3xl`, no
|
|
150
|
+
collapse control, ordinary page scrolling — the `/cart` review route).
|
|
151
|
+
Omitting `presentation` renders the compact card byte-identically to before.
|
|
152
|
+
- Line amounts prefer the canonical `lineTotal?: Money` and fall back to the
|
|
153
|
+
legacy numeric `price * quantity` only when `lineTotal` is absent. A missing or
|
|
154
|
+
malformed `Money` renders the `amountUnavailableLabel` (never a fabricated
|
|
155
|
+
zero or a currency fallback). `unitPrice?: Money` is carried verbatim.
|
|
156
|
+
- `totalsState` (`'idle' | 'pending' | 'error'`) plus `onRetryTotals` make the
|
|
157
|
+
totals controlled: pending retains the last confirmed totals and disables
|
|
158
|
+
conflicting mutations; error shows the error label and a retry.
|
|
159
|
+
`onQuantityChange(id, quantity)` reports the **absolute** line quantity (keyed
|
|
160
|
+
by backend line id) and `onRemove(id)` removes by the same id.
|
|
161
|
+
`checkoutUnavailable` hides the checkout action (e.g. no checkout installed)
|
|
162
|
+
and `checkoutDisabled` disables it (e.g. pending or invalid totals).
|
|
163
|
+
|
|
164
|
+
`Navbar4` owns the lateral. Pass `cartOpen` + `onCartOpenChange` to control the
|
|
165
|
+
sheet's visibility from host state (omit both to keep the legacy uncontrolled
|
|
166
|
+
sheet); the block keeps `aria-expanded`/`data-state` in sync. Its cart sheet
|
|
167
|
+
(`Navbar4CartSheet`) takes an optional `canonical` mode where each line shows the
|
|
168
|
+
canonical `lineTotal` (never the placeholder numeric price), plus
|
|
169
|
+
`checkoutUnavailable`/`viewCartUnavailable` to hide actions the store cannot
|
|
170
|
+
serve, and a `state` (`'idle' | 'pending' | 'error'`) with retry for read/mutation
|
|
171
|
+
feedback.
|
|
172
|
+
|
|
94
173
|
## Checkout blocks (controlled)
|
|
95
174
|
|
|
96
175
|
`CheckoutForm1` (3-step wizard) and `CheckoutForm2` (single page) are **controlled components**: they receive the current form values through a `values` prop and report every edit through `onChange`. They hold no internal form state, so a renderer's validation context can read field values from its own state model. `CheckoutForm3` (4-step wizard) keeps the same contract with internal step state.
|
|
@@ -149,6 +228,20 @@ unique by contract, not by convention. See
|
|
|
149
228
|
[`docs/standards/data-contracts.md`](docs/standards/data-contracts.md) for the
|
|
150
229
|
rules and the review checklist.
|
|
151
230
|
|
|
231
|
+
Optional numeric projections are omitted rather than fabricated: e.g.
|
|
232
|
+
`ProductCategory2Category.itemCount` renders a count only when it is a supplied
|
|
233
|
+
finite non-negative number (a real `0` is preserved); an unknown count renders
|
|
234
|
+
no count text, never a fabricated `0`.
|
|
235
|
+
|
|
236
|
+
Product presentations (`ProductCard1`, `ProductShowcase1`) accept either the
|
|
237
|
+
legacy numeric-price props or a canonical `ProductPresentation` (`price`/
|
|
238
|
+
`compareAtPrice` as `Money`, `{ amount: string, currencyCode: string }` in
|
|
239
|
+
decimal major units). The canonical path formats with the store currency and
|
|
240
|
+
locale, renders a truthful "unavailable" state for an unresolved price (never
|
|
241
|
+
`$0`; a valid `0` is preserved), and shows a comparison price only when it is
|
|
242
|
+
valid and strictly higher. Optional rating/badge/image appear only when
|
|
243
|
+
supplied; a missing image is omitted, never `src=""`.
|
|
244
|
+
|
|
152
245
|
## Block interaction contracts
|
|
153
246
|
|
|
154
247
|
State and events between a block, its host registry, and the store must follow
|