@thorprovider/blocks 0.1.3 → 2.0.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 +155 -0
- package/README.md +228 -68
- package/docs/standards/data-contracts.md +13 -2
- package/package.json +26 -10
- package/scripts/fix-esm-extensions.mjs +40 -0
- package/src/blocks/application/login-forms/login-page.test.tsx +190 -0
- package/src/blocks/application/login-forms/login-page.tsx +240 -0
- package/src/blocks/application/password-recovery/forgot-password-page-1.tsx +6 -8
- package/src/blocks/application/signup-forms/signup-page-1.tsx +127 -129
- package/src/blocks/application/verification/verify-1.tsx +2 -2
- package/src/blocks/application/viewport-ownership.test.tsx +41 -0
- package/src/blocks/e-commerce/category-filters/category-listing-filter-fields.tsx +218 -0
- package/src/blocks/e-commerce/category-filters/{category-filter-2.test.tsx → category-listing.test.tsx} +287 -199
- package/src/blocks/e-commerce/category-filters/category-listing.tsx +934 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-contact-step.tsx +149 -0
- package/src/blocks/e-commerce/checkout-forms/{checkout-form-1-country-field.tsx → checkout-country-field.tsx} +10 -8
- package/src/blocks/e-commerce/checkout-forms/checkout-order-summary.tsx +230 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-payment-step.tsx +100 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-progress.tsx +62 -0
- package/src/blocks/e-commerce/checkout-forms/checkout-review-step.tsx +59 -0
- package/src/blocks/e-commerce/checkout-forms/{checkout-form-1-shipping-step.tsx → checkout-shipping-step.tsx} +65 -41
- package/src/blocks/e-commerce/checkout-forms/checkout.test.tsx +478 -0
- package/src/blocks/e-commerce/checkout-forms/checkout.tsx +550 -0
- package/src/blocks/e-commerce/navigation/storefront-navbar-account-menu.test.tsx +56 -0
- package/src/blocks/{marketing/navbars/navbar-4-account-menu.tsx → e-commerce/navigation/storefront-navbar-account-menu.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4-cart-sheet.test.tsx → e-commerce/navigation/storefront-navbar-cart-sheet.test.tsx} +22 -22
- package/src/blocks/{marketing/navbars/navbar-4-cart-sheet.tsx → e-commerce/navigation/storefront-navbar-cart-sheet.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4-mobile-nav.tsx → e-commerce/navigation/storefront-navbar-mobile-nav.tsx} +4 -12
- package/src/blocks/{marketing/navbars/navbar-4-search-bar.tsx → e-commerce/navigation/storefront-navbar-search-bar.tsx} +3 -3
- package/src/blocks/{marketing/navbars/navbar-4.test.tsx → e-commerce/navigation/storefront-navbar.test.tsx} +67 -36
- package/src/blocks/{marketing/navbars/navbar-4.tsx → e-commerce/navigation/storefront-navbar.tsx} +43 -25
- package/src/blocks/e-commerce/product-categories/category-card-grid.test.tsx +122 -0
- package/src/blocks/e-commerce/product-categories/category-card.test.tsx +68 -0
- package/src/blocks/e-commerce/product-categories/category-card.tsx +172 -0
- package/src/blocks/e-commerce/product-categories/category-grid.test.tsx +67 -0
- package/src/blocks/e-commerce/product-categories/category-shared.tsx +109 -0
- package/src/blocks/e-commerce/product-categories/product-category-grid.tsx +170 -0
- package/src/blocks/e-commerce/product-categories/product-category.test.tsx +266 -0
- package/src/blocks/e-commerce/product-categories/product-category.tsx +462 -0
- package/src/blocks/e-commerce/product-list/product-card.test.tsx +263 -0
- package/src/blocks/e-commerce/product-list/product-card.tsx +447 -0
- package/src/blocks/e-commerce/product-list/product-grid.test.tsx +162 -0
- package/src/blocks/e-commerce/product-list/product-grid.tsx +114 -0
- package/src/blocks/e-commerce/product-overview/product-overview-gallery.tsx +71 -0
- package/src/blocks/e-commerce/product-overview/{product-overview-5-lightbox-tab.tsx → product-overview-lightbox-tab.tsx} +35 -23
- package/src/blocks/e-commerce/product-overview/{product-overview-5-reviews-tab.tsx → product-overview-reviews-tab.tsx} +40 -17
- package/src/blocks/e-commerce/product-overview/{product-overview-5-tabs.tsx → product-overview-tabs.tsx} +8 -7
- package/src/blocks/e-commerce/product-overview/product-overview.test.tsx +283 -0
- package/src/blocks/e-commerce/product-overview/product-overview.tsx +1186 -0
- package/src/blocks/e-commerce/reviews/review-rating-2.tsx +5 -6
- package/src/blocks/e-commerce/shopping-carts/shopping-cart.test.tsx +399 -0
- package/src/blocks/e-commerce/shopping-carts/{shopping-cart-4.tsx → shopping-cart.tsx} +119 -85
- package/src/blocks/e-commerce/storefront-hero/storefront-hero.test.tsx +412 -0
- package/src/blocks/e-commerce/storefront-hero/storefront-hero.tsx +1283 -0
- package/src/blocks/marketing/features/feature.test.tsx +153 -0
- package/src/blocks/marketing/features/feature.tsx +195 -0
- package/src/blocks/marketing/footers/footer-section-accessibility.test.tsx +118 -0
- package/src/blocks/marketing/footers/footer-section-actions.test.tsx +131 -0
- package/src/blocks/marketing/footers/footer-section-data.test.tsx +127 -0
- package/src/blocks/marketing/footers/footer-section-native-links.test.tsx +100 -0
- package/src/blocks/marketing/footers/footer-section-public-api.test.tsx +11 -0
- package/src/blocks/marketing/footers/footer-section.test.tsx +46 -0
- package/src/blocks/marketing/footers/footer-section.tsx +532 -0
- package/src/blocks/marketing/navbars/navbar-public-api.test.tsx +57 -0
- package/src/blocks/marketing/navbars/navbar.mega.test.tsx +149 -0
- package/src/blocks/marketing/navbars/navbar.test.tsx +155 -0
- package/src/blocks/marketing/navbars/navbar.tsx +735 -0
- package/src/blocks/marketing/testimonials/testimonial-section.test.tsx +171 -0
- package/src/blocks/marketing/testimonials/testimonial-section.tsx +237 -0
- package/src/index.ts +156 -128
- package/src/lib/contracts-curated.test.ts +47 -29
- package/src/lib/contracts.test.ts +198 -2
- package/src/lib/contracts.ts +410 -16
- package/src/ui/button-group.tsx +1 -1
- package/src/ui/carousel.tsx +1 -1
- package/src/ui/dialog.tsx +1 -1
- package/src/ui/field.tsx +2 -2
- package/src/ui/input-group.tsx +3 -3
- package/src/ui/pagination.tsx +1 -1
- package/src/ui/sidebar.tsx +7 -7
- package/src/ui/toggle-group.tsx +1 -1
- package/tsconfig.build.json +12 -0
- package/tsup.config.ts +11 -7
- package/.turbo/turbo-build.log +0 -24
- package/.turbo/turbo-test.log +0 -47
- package/.turbo/turbo-type-check.log +0 -0
- package/dist/.tsbuildinfo +0 -1
- package/dist/contracts.d.mts +0 -1732
- package/dist/contracts.d.ts +0 -1732
- package/dist/contracts.js +0 -423
- package/dist/contracts.js.map +0 -1
- package/dist/contracts.mjs +0 -365
- package/dist/contracts.mjs.map +0 -1
- package/dist/index.d.mts +0 -3068
- package/dist/index.d.ts +0 -3068
- package/dist/index.js +0 -17834
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -17740
- package/dist/index.mjs.map +0 -1
- package/src/blocks/application/login-forms/login-page-1.tsx +0 -246
- package/src/blocks/application/login-forms/login-page-2.tsx +0 -207
- package/src/blocks/e-commerce/category-filters/category-filter-1.tsx +0 -260
- package/src/blocks/e-commerce/category-filters/category-filter-2-filter-panel.tsx +0 -222
- package/src/blocks/e-commerce/category-filters/category-filter-2.tsx +0 -921
- package/src/blocks/e-commerce/category-filters/category-filter-4-chip-rail.tsx +0 -57
- package/src/blocks/e-commerce/category-filters/category-filter-4-drawer.tsx +0 -124
- package/src/blocks/e-commerce/category-filters/category-filter-4-fields.tsx +0 -170
- package/src/blocks/e-commerce/category-filters/category-filter-4-sidebar.tsx +0 -52
- package/src/blocks/e-commerce/category-filters/category-filter-4-sort-sheet.tsx +0 -57
- package/src/blocks/e-commerce/category-filters/category-filter-4-state.ts +0 -68
- package/src/blocks/e-commerce/category-filters/category-filter-4.tsx +0 -298
- package/src/blocks/e-commerce/checkout-forms/card-formatting.test.ts +0 -47
- package/src/blocks/e-commerce/checkout-forms/card-formatting.ts +0 -9
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-contact-step.tsx +0 -96
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-order-summary.tsx +0 -252
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-payment-step.tsx +0 -188
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1-progress.tsx +0 -36
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.test.tsx +0 -216
- package/src/blocks/e-commerce/checkout-forms/checkout-form-1.tsx +0 -338
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-order-summary.tsx +0 -130
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-payment-card.tsx +0 -175
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2-shipping-card.tsx +0 -190
- package/src/blocks/e-commerce/checkout-forms/checkout-form-2.tsx +0 -312
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-information-step.tsx +0 -91
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-order-summary.tsx +0 -110
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-payment-step.tsx +0 -137
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-progress.tsx +0 -68
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-review-step.tsx +0 -79
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3-shipping-step.tsx +0 -172
- package/src/blocks/e-commerce/checkout-forms/checkout-form-3.tsx +0 -392
- package/src/blocks/e-commerce/product-categories/avatar-group.tsx +0 -86
- package/src/blocks/e-commerce/product-categories/product-category-1.tsx +0 -126
- package/src/blocks/e-commerce/product-categories/product-category-2.test.tsx +0 -51
- package/src/blocks/e-commerce/product-categories/product-category-2.tsx +0 -120
- package/src/blocks/e-commerce/product-categories/product-category-4.tsx +0 -129
- package/src/blocks/e-commerce/product-categories/product-category-5.tsx +0 -218
- package/src/blocks/e-commerce/product-list/product-card-1.test.tsx +0 -88
- package/src/blocks/e-commerce/product-list/product-card-1.tsx +0 -192
- package/src/blocks/e-commerce/product-list/product-card-2.tsx +0 -71
- package/src/blocks/e-commerce/product-list/product-card-3-reaction-toggle.tsx +0 -166
- package/src/blocks/e-commerce/product-list/product-card-3.tsx +0 -215
- package/src/blocks/e-commerce/product-list/product-card-5-checkbox-check.tsx +0 -98
- package/src/blocks/e-commerce/product-list/product-card-5-reaction-toggle.tsx +0 -171
- package/src/blocks/e-commerce/product-list/product-card-5.tsx +0 -367
- package/src/blocks/e-commerce/product-overview/product-overview-1.test.tsx +0 -182
- package/src/blocks/e-commerce/product-overview/product-overview-1.tsx +0 -370
- package/src/blocks/e-commerce/product-overview/product-overview-2.tsx +0 -272
- package/src/blocks/e-commerce/product-overview/product-overview-5-gallery.tsx +0 -59
- package/src/blocks/e-commerce/product-overview/product-overview-5.tsx +0 -274
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-1-spinning-counter.tsx +0 -142
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-1.tsx +0 -291
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-item-row.tsx +0 -110
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-recommendations.tsx +0 -51
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2-spinning-counter.tsx +0 -146
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-2.tsx +0 -295
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-3-spinning-counter.tsx +0 -142
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-3.tsx +0 -342
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4-spinning-counter.tsx +0 -146
- package/src/blocks/e-commerce/shopping-carts/shopping-cart-4.test.tsx +0 -229
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.test.tsx +0 -72
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-1.tsx +0 -263
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-2.tsx +0 -283
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-5.tsx +0 -318
- package/src/blocks/e-commerce/storefront-hero/storefront-hero-6.tsx +0 -205
- package/src/blocks/marketing/features/feature-1.tsx +0 -97
- package/src/blocks/marketing/features/feature-2.tsx +0 -82
- package/src/blocks/marketing/footers/footer-section-1.test.tsx +0 -117
- package/src/blocks/marketing/footers/footer-section-1.tsx +0 -178
- package/src/blocks/marketing/footers/footer-section-3.tsx +0 -192
- package/src/blocks/marketing/footers/footer-section-4.tsx +0 -355
- package/src/blocks/marketing/navbars/navbar-1.tsx +0 -267
- package/src/blocks/marketing/navbars/navbar-2.tsx +0 -351
- package/src/blocks/marketing/navbars/navbar-3.tsx +0 -303
- package/src/blocks/marketing/navbars/navbar-4-account-menu.test.tsx +0 -38
- package/src/blocks/marketing/navbars/navbar-4-like-button.tsx +0 -177
- package/src/blocks/marketing/navbars/navbar-4-product-grid.tsx +0 -219
- package/src/blocks/marketing/testimonials/testimonial-1.tsx +0 -141
- package/src/blocks/marketing/testimonials/testimonial-2.tsx +0 -108
package/src/lib/contracts.ts
CHANGED
|
@@ -95,13 +95,31 @@ export const productDetailProductSchema = z.object({
|
|
|
95
95
|
})
|
|
96
96
|
export type ProductDetailProductSpec = z.infer<typeof productDetailProductSchema>
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Canonical ProductOverview contract. Uses the canonical product projection and adds the
|
|
100
|
+
* bounded `presentation` option plus the `rich` presentation's optional data. Callbacks are not
|
|
101
|
+
* part of the schema (they are runtime props).
|
|
102
|
+
*/
|
|
103
|
+
export const productOverviewReviewSchema = z.object({
|
|
104
|
+
id: z.number(),
|
|
105
|
+
author: z.string(),
|
|
106
|
+
rating: z.number(),
|
|
107
|
+
comment: z.string(),
|
|
108
|
+
date: z.string(),
|
|
109
|
+
helpful: z.number().optional(),
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
export const productOverviewPropsSchema = z.object({
|
|
99
113
|
product: productDetailProductSchema,
|
|
114
|
+
presentation: z.enum(['standard', 'gallery', 'rich']).optional(),
|
|
100
115
|
selectedVariantId: z.string().nullable().optional(),
|
|
101
116
|
quantity: z.number().optional(),
|
|
102
117
|
rating: z.object({ value: z.number(), count: z.number() }).optional(),
|
|
103
118
|
deliveryEstimate: z.string().optional(),
|
|
104
119
|
shipping: moneySchema.optional(),
|
|
120
|
+
specifications: z.record(z.string(), z.string()).optional(),
|
|
121
|
+
features: z.array(z.string()).optional(),
|
|
122
|
+
reviews: z.array(productOverviewReviewSchema).optional(),
|
|
105
123
|
sizesLabel: z.string().optional(),
|
|
106
124
|
variantLabel: z.string().optional(),
|
|
107
125
|
reviewsLabel: z.string().optional(),
|
|
@@ -112,8 +130,24 @@ export const productOverview1PropsSchema = z.object({
|
|
|
112
130
|
quantityLabel: z.string().optional(),
|
|
113
131
|
deliveryEstimateLabel: z.string().optional(),
|
|
114
132
|
shippingLabel: z.string().optional(),
|
|
133
|
+
badgeLabel: z.string().optional(),
|
|
134
|
+
availabilityLabel: z.string().optional(),
|
|
135
|
+
skuLabel: z.string().optional(),
|
|
136
|
+
overviewLabel: z.string().optional(),
|
|
137
|
+
specsLabel: z.string().optional(),
|
|
138
|
+
featuresLabel: z.string().optional(),
|
|
139
|
+
specificationsLabel: z.string().optional(),
|
|
140
|
+
galleryLabel: z.string().optional(),
|
|
141
|
+
photosLabel: z.string().optional(),
|
|
142
|
+
saveLabel: z.string().optional(),
|
|
143
|
+
savedLabel: z.string().optional(),
|
|
144
|
+
shareLabel: z.string().optional(),
|
|
145
|
+
basedOnReviewsLabel: z.string().optional(),
|
|
146
|
+
foundHelpfulLabel: z.string().optional(),
|
|
147
|
+
ofCounterLabel: z.string().optional(),
|
|
148
|
+
freeDeliveryLabel: z.string().optional(),
|
|
115
149
|
})
|
|
116
|
-
export type
|
|
150
|
+
export type ProductOverviewSpecProps = z.infer<typeof productOverviewPropsSchema>
|
|
117
151
|
|
|
118
152
|
export const cardProductSchema = z.object({
|
|
119
153
|
id: z.union([z.string(), z.number()]),
|
|
@@ -275,13 +309,6 @@ export const storeContainer1PropsSchema = z.object({
|
|
|
275
309
|
})
|
|
276
310
|
export type StoreContainer1SpecProps = z.infer<typeof storeContainer1PropsSchema>
|
|
277
311
|
|
|
278
|
-
export const productCard1PropsSchema = z.object({
|
|
279
|
-
products: z.array(cardProductSchema),
|
|
280
|
-
heading: z.string().optional(),
|
|
281
|
-
maxItems: z.number().int().positive().optional(),
|
|
282
|
-
})
|
|
283
|
-
export type ProductCard1SpecProps = z.infer<typeof productCard1PropsSchema>
|
|
284
|
-
|
|
285
312
|
/**
|
|
286
313
|
* Canonical product presentation — the serializable projection a storefront host
|
|
287
314
|
* produces from a canonical `Product` for the merchandising sections. Unlike
|
|
@@ -310,6 +337,42 @@ export const productPresentationSchema = z.object({
|
|
|
310
337
|
})
|
|
311
338
|
export type ProductPresentation = z.infer<typeof productPresentationSchema>
|
|
312
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Canonical product card contract (item cell of a product listing). The cell
|
|
342
|
+
* consumes one canonical `ProductPresentation` projection only — the legacy
|
|
343
|
+
* numeric-price card shape is not accepted. `presentation` is the bounded
|
|
344
|
+
* structure switch (`classic`/`minimal`/`rich`) and `wishlisted` is the
|
|
345
|
+
* host-resolved membership state; callbacks and label strings are runtime
|
|
346
|
+
* props and are excluded here. Collection concerns (heading, item cap, loading
|
|
347
|
+
* and empty states) belong to `ProductGrid`.
|
|
348
|
+
*/
|
|
349
|
+
export const productCardPropsSchema = z.object({
|
|
350
|
+
item: productPresentationSchema,
|
|
351
|
+
presentation: z.enum(['classic', 'minimal', 'rich']).optional(),
|
|
352
|
+
wishlisted: z.boolean().optional(),
|
|
353
|
+
})
|
|
354
|
+
export type ProductCardSpecProps = z.infer<typeof productCardPropsSchema>
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Canonical product grid contract (listing). Consumes a collection of
|
|
358
|
+
* canonical `ProductPresentation` items and owns the listing's heading, item
|
|
359
|
+
* cap, wishlist membership, and loading/empty/ready states. `wishlistedIds` is
|
|
360
|
+
* resolved per cell before rendering, so the cell receives only its own
|
|
361
|
+
* boolean. Callbacks and label strings are runtime props and are excluded
|
|
362
|
+
* here. Error state belongs to the host.
|
|
363
|
+
*/
|
|
364
|
+
export const productGridPropsSchema = z.object({
|
|
365
|
+
items: z.array(productPresentationSchema),
|
|
366
|
+
presentation: z.enum(['classic', 'minimal', 'rich']).optional(),
|
|
367
|
+
heading: z.string().optional(),
|
|
368
|
+
maxItems: z.number().int().positive().optional(),
|
|
369
|
+
wishlistedIds: z.array(z.union([z.string(), z.number()])).readonly().optional(),
|
|
370
|
+
loading: z.boolean().optional(),
|
|
371
|
+
skeletonCount: z.number().int().positive().optional(),
|
|
372
|
+
emptyLabel: z.string().optional(),
|
|
373
|
+
})
|
|
374
|
+
export type ProductGridSpecProps = z.infer<typeof productGridPropsSchema>
|
|
375
|
+
|
|
313
376
|
/**
|
|
314
377
|
* Serializable contract for the combined grid-and-carousel product
|
|
315
378
|
* presentation (`ProductShowcase1`). The grid pages are fixed-size, navigated
|
|
@@ -330,10 +393,45 @@ export const productShowcase1PropsSchema = z.object({
|
|
|
330
393
|
})
|
|
331
394
|
export type ProductShowcase1SpecProps = z.infer<typeof productShowcase1PropsSchema>
|
|
332
395
|
|
|
333
|
-
|
|
334
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Canonical shopping cart contract (consolidated shopping-cart family). Lines
|
|
398
|
+
* are keyed by the backend cart line-item id and carry canonical `Money`
|
|
399
|
+
* amounts only — the legacy numeric-price shape is not accepted: a line always
|
|
400
|
+
* carries the backend-authoritative `lineTotal`, and an optional `unitPrice` is
|
|
401
|
+
* carried verbatim (never used for a local `price * quantity` computation).
|
|
402
|
+
* Suggestions fold the numbered carts' recommendations: optional image (omitted
|
|
403
|
+
* when absent) and optional canonical `Money` price. `presentation` is the
|
|
404
|
+
* bounded structure switch (`compact`/`page`); callbacks and interaction state
|
|
405
|
+
* are runtime props and are excluded here.
|
|
406
|
+
*/
|
|
407
|
+
export const shoppingCartItemSchema = z.object({
|
|
408
|
+
id: z.string(),
|
|
409
|
+
name: z.string(),
|
|
410
|
+
quantity: z.number().int().min(0),
|
|
411
|
+
/** Optional; absent images are omitted, never serialized as `""`. */
|
|
412
|
+
image: z.string().optional(),
|
|
413
|
+
variant: z.string().optional(),
|
|
414
|
+
/** Canonical backend line total; a malformed amount renders as unavailable. */
|
|
415
|
+
lineTotal: moneySchema,
|
|
416
|
+
/** Canonical backend unit price; carried verbatim, never used locally. */
|
|
417
|
+
unitPrice: moneySchema.optional(),
|
|
418
|
+
})
|
|
419
|
+
export type ShoppingCartItem = z.infer<typeof shoppingCartItemSchema>
|
|
420
|
+
|
|
421
|
+
export const shoppingCartSuggestionSchema = z.object({
|
|
422
|
+
id: z.string(),
|
|
423
|
+
name: z.string(),
|
|
424
|
+
/** Optional; absent images are omitted, never serialized as `""`. */
|
|
425
|
+
image: z.string().optional(),
|
|
426
|
+
unitPrice: moneySchema.optional(),
|
|
427
|
+
})
|
|
428
|
+
export type ShoppingCartSuggestion = z.infer<typeof shoppingCartSuggestionSchema>
|
|
429
|
+
|
|
430
|
+
export const shoppingCartPropsSchema = z.object({
|
|
431
|
+
items: z.array(shoppingCartItemSchema),
|
|
335
432
|
promotions: z.array(promotionSchema).default([]),
|
|
336
|
-
recentlyViewed: z.array(
|
|
433
|
+
recentlyViewed: z.array(shoppingCartSuggestionSchema).optional(),
|
|
434
|
+
presentation: z.enum(['compact', 'page']).optional(),
|
|
337
435
|
/** Backend-authoritative totals; rendered verbatim, never computed locally. */
|
|
338
436
|
totals: cartTotalsSchema.optional(),
|
|
339
437
|
totalsState: z.enum(['idle', 'pending', 'error']).optional(),
|
|
@@ -341,7 +439,6 @@ export const shoppingCart4PropsSchema = z.object({
|
|
|
341
439
|
totalsUnavailableLabel: z.string().optional(),
|
|
342
440
|
amountUnavailableLabel: z.string().optional(),
|
|
343
441
|
retryLabel: z.string().optional(),
|
|
344
|
-
taxRate: z.number().optional(),
|
|
345
442
|
titleLabel: z.string().optional(),
|
|
346
443
|
subtotalLabel: z.string().optional(),
|
|
347
444
|
discountLabel: z.string().optional(),
|
|
@@ -359,6 +456,9 @@ export const shoppingCart4PropsSchema = z.object({
|
|
|
359
456
|
estimatedDeliveryLabel: z.string().optional(),
|
|
360
457
|
secureCheckoutLabel: z.string().optional(),
|
|
361
458
|
recentlyViewedLabel: z.string().optional(),
|
|
459
|
+
promoPromptLabel: z.string().optional(),
|
|
460
|
+
promoPlaceholderLabel: z.string().optional(),
|
|
461
|
+
promoApplyLabel: z.string().optional(),
|
|
362
462
|
collapseLabel: z.string().optional(),
|
|
363
463
|
expandLabel: z.string().optional(),
|
|
364
464
|
checkoutLabel: z.string().optional(),
|
|
@@ -369,7 +469,7 @@ export const shoppingCart4PropsSchema = z.object({
|
|
|
369
469
|
decreaseLabel: z.string().optional(),
|
|
370
470
|
increaseLabel: z.string().optional(),
|
|
371
471
|
})
|
|
372
|
-
export type
|
|
472
|
+
export type ShoppingCartSpecProps = z.infer<typeof shoppingCartPropsSchema>
|
|
373
473
|
|
|
374
474
|
/**
|
|
375
475
|
* Optional brand seams shared by the existing blocks. These mirror the
|
|
@@ -395,7 +495,12 @@ export const heroImageSchema = z.object({
|
|
|
395
495
|
})
|
|
396
496
|
export type HeroImage = z.infer<typeof heroImageSchema>
|
|
397
497
|
|
|
398
|
-
|
|
498
|
+
/**
|
|
499
|
+
* Serializable contract for the canonical commerce storefront shell
|
|
500
|
+
* (`StorefrontNavbar`). Identity, cart, and search state stay host-owned: the
|
|
501
|
+
* schema carries content and display state only, never cart arithmetic.
|
|
502
|
+
*/
|
|
503
|
+
export const storefrontNavbarPropsSchema = z.object({
|
|
399
504
|
storeCategories: z.array(storeCategorySchema),
|
|
400
505
|
shippingNote: z.string().optional(),
|
|
401
506
|
utilityLinks: z.array(utilityLinkSchema),
|
|
@@ -419,7 +524,7 @@ export const navbar4PropsSchema = z.object({
|
|
|
419
524
|
accountPending: z.boolean().optional(),
|
|
420
525
|
accountUnavailable: z.boolean().optional(),
|
|
421
526
|
})
|
|
422
|
-
export type
|
|
527
|
+
export type StorefrontNavbarSpecProps = z.infer<typeof storefrontNavbarPropsSchema>
|
|
423
528
|
|
|
424
529
|
/**
|
|
425
530
|
* Serializable contracts for the two bounded editorial sections (`faq`, `cta`).
|
|
@@ -433,6 +538,172 @@ export const ctaSchema = z.object({
|
|
|
433
538
|
})
|
|
434
539
|
export type CtaSpec = z.infer<typeof ctaSchema>
|
|
435
540
|
|
|
541
|
+
/** Bounded presentations of the page-level navigation header. */
|
|
542
|
+
export const navbarPresentationSchema = z.enum(['bar', 'mega', 'floating'])
|
|
543
|
+
export type NavbarPresentationSpec = z.infer<typeof navbarPresentationSchema>
|
|
544
|
+
|
|
545
|
+
export const navbarItemSchema = z.object({
|
|
546
|
+
label: z.string(),
|
|
547
|
+
href: z.string(),
|
|
548
|
+
description: z.string().optional(),
|
|
549
|
+
/** Key resolved through the consumer's host-bound `iconMap`. */
|
|
550
|
+
icon: z.string().optional(),
|
|
551
|
+
})
|
|
552
|
+
export type NavbarItemSpec = z.infer<typeof navbarItemSchema>
|
|
553
|
+
|
|
554
|
+
export const navbarGroupSchema = z.object({
|
|
555
|
+
title: z.string().optional(),
|
|
556
|
+
items: z.array(navbarItemSchema),
|
|
557
|
+
})
|
|
558
|
+
export type NavbarGroupSpec = z.infer<typeof navbarGroupSchema>
|
|
559
|
+
|
|
560
|
+
export const navbarLinkSchema = z.object({
|
|
561
|
+
label: z.string(),
|
|
562
|
+
href: z.string().optional(),
|
|
563
|
+
groups: z.array(navbarGroupSchema).optional(),
|
|
564
|
+
emphasis: z.boolean().optional(),
|
|
565
|
+
})
|
|
566
|
+
export type NavbarLinkSpec = z.infer<typeof navbarLinkSchema>
|
|
567
|
+
|
|
568
|
+
export const navbarFeaturedSchema = z.object({
|
|
569
|
+
eyebrow: z.string(),
|
|
570
|
+
title: z.string(),
|
|
571
|
+
description: z.string().optional(),
|
|
572
|
+
href: z.string(),
|
|
573
|
+
linkLabel: z.string().optional(),
|
|
574
|
+
image: z.string().optional(),
|
|
575
|
+
imageAlt: z.string().optional(),
|
|
576
|
+
})
|
|
577
|
+
export type NavbarFeaturedSpec = z.infer<typeof navbarFeaturedSchema>
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Serializable contract for the canonical page-level header (`Navbar`). The
|
|
581
|
+
* serializable subset excludes the React-only bindings: `iconMap`, `onSignIn`,
|
|
582
|
+
* and `onCtaClick` are bound by the host, exactly like the footer's icon map.
|
|
583
|
+
*/
|
|
584
|
+
export const navbarPropsSchema = z.object({
|
|
585
|
+
presentation: navbarPresentationSchema.optional(),
|
|
586
|
+
logoText: z.string(),
|
|
587
|
+
logoHref: z.string().optional(),
|
|
588
|
+
currentPath: z.string().optional(),
|
|
589
|
+
links: z.array(navbarLinkSchema),
|
|
590
|
+
featured: navbarFeaturedSchema.optional(),
|
|
591
|
+
signIn: ctaSchema.optional(),
|
|
592
|
+
cta: ctaSchema.optional(),
|
|
593
|
+
/** Consumer-supplied classes merged onto the header surface last. */
|
|
594
|
+
className: z.string().optional(),
|
|
595
|
+
})
|
|
596
|
+
export type NavbarSpecProps = z.infer<typeof navbarPropsSchema>
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Serializable subset of the canonical `StorefrontHero`'s props (callbacks
|
|
600
|
+
* excluded). Every popularity, review, count, or countdown field is optional
|
|
601
|
+
* host-supplied evidence: omitted fields render nothing (honest omission)
|
|
602
|
+
* instead of fabricated defaults, and prices are formatted from the supplied
|
|
603
|
+
* ISO 4217 `currency` via `Intl.NumberFormat` (never hardcoded).
|
|
604
|
+
*/
|
|
605
|
+
export const storefrontHeroProductSchema = z.object({
|
|
606
|
+
id: z.string(),
|
|
607
|
+
name: z.string(),
|
|
608
|
+
price: z.number(),
|
|
609
|
+
originalPrice: z.number().optional(),
|
|
610
|
+
image: z.string().optional(),
|
|
611
|
+
imageAlt: z.string().optional(),
|
|
612
|
+
brand: z.string().optional(),
|
|
613
|
+
colors: z.array(z.string()).optional(),
|
|
614
|
+
rating: z.number().optional(),
|
|
615
|
+
reviewCount: z.number().optional(),
|
|
616
|
+
inStock: z.boolean().optional(),
|
|
617
|
+
isNew: z.boolean().optional(),
|
|
618
|
+
tag: z.string().optional(),
|
|
619
|
+
})
|
|
620
|
+
export type StorefrontHeroProduct = z.infer<typeof storefrontHeroProductSchema>
|
|
621
|
+
|
|
622
|
+
export const storefrontHeroPropsSchema = z.object({
|
|
623
|
+
title: z.string(),
|
|
624
|
+
description: z.string(),
|
|
625
|
+
presentation: z.enum(['compact', 'showcase', 'editorial', 'promotional']).optional(),
|
|
626
|
+
currency: z.string().optional(),
|
|
627
|
+
products: z.array(storefrontHeroProductSchema),
|
|
628
|
+
badge: z.string().optional(),
|
|
629
|
+
titleAccent: z.string().optional(),
|
|
630
|
+
primaryCta: ctaSchema.optional(),
|
|
631
|
+
secondaryCta: ctaSchema.optional(),
|
|
632
|
+
heroImage: heroImageSchema.optional(),
|
|
633
|
+
departments: z
|
|
634
|
+
.array(
|
|
635
|
+
z.object({
|
|
636
|
+
id: z.string(),
|
|
637
|
+
name: z.string(),
|
|
638
|
+
image: z.string().optional(),
|
|
639
|
+
imageAlt: z.string().optional(),
|
|
640
|
+
count: z.string().optional(),
|
|
641
|
+
href: z.string().optional(),
|
|
642
|
+
}),
|
|
643
|
+
)
|
|
644
|
+
.optional(),
|
|
645
|
+
featuredDeals: z
|
|
646
|
+
.array(
|
|
647
|
+
z.object({
|
|
648
|
+
id: z.string(),
|
|
649
|
+
name: z.string(),
|
|
650
|
+
description: z.string().optional(),
|
|
651
|
+
image: z.string().optional(),
|
|
652
|
+
imageAlt: z.string().optional(),
|
|
653
|
+
price: z.number(),
|
|
654
|
+
originalPrice: z.number().optional(),
|
|
655
|
+
cta: ctaSchema.optional(),
|
|
656
|
+
}),
|
|
657
|
+
)
|
|
658
|
+
.optional(),
|
|
659
|
+
storeLocator: z
|
|
660
|
+
.object({
|
|
661
|
+
title: z.string(),
|
|
662
|
+
description: z.string(),
|
|
663
|
+
ctaLabel: z.string(),
|
|
664
|
+
ctaHref: z.string().optional(),
|
|
665
|
+
})
|
|
666
|
+
.optional(),
|
|
667
|
+
shippingInfo: z.string().optional(),
|
|
668
|
+
deals: z
|
|
669
|
+
.array(
|
|
670
|
+
z.object({
|
|
671
|
+
id: z.string(),
|
|
672
|
+
title: z.string(),
|
|
673
|
+
discount: z.string().optional(),
|
|
674
|
+
endTime: z.string().optional(),
|
|
675
|
+
}),
|
|
676
|
+
)
|
|
677
|
+
.optional(),
|
|
678
|
+
categories: z
|
|
679
|
+
.array(
|
|
680
|
+
z.object({
|
|
681
|
+
id: z.string(),
|
|
682
|
+
name: z.string(),
|
|
683
|
+
image: z.string().optional(),
|
|
684
|
+
imageAlt: z.string().optional(),
|
|
685
|
+
count: z.string().optional(),
|
|
686
|
+
href: z.string().optional(),
|
|
687
|
+
}),
|
|
688
|
+
)
|
|
689
|
+
.optional(),
|
|
690
|
+
rotationInterval: z.number().optional(),
|
|
691
|
+
addToCartLabel: z.string().optional(),
|
|
692
|
+
buyNowLabel: z.string().optional(),
|
|
693
|
+
newLabel: z.string().optional(),
|
|
694
|
+
outOfStockLabel: z.string().optional(),
|
|
695
|
+
colorsLabel: z.string().optional(),
|
|
696
|
+
discountSuffixLabel: z.string().optional(),
|
|
697
|
+
searchPlaceholder: z.string().optional(),
|
|
698
|
+
searchLabel: z.string().optional(),
|
|
699
|
+
featuredDescription: z.string().optional(),
|
|
700
|
+
shopNowLabel: z.string().optional(),
|
|
701
|
+
endsInLabel: z.string().optional(),
|
|
702
|
+
productsLabel: z.string().optional(),
|
|
703
|
+
viewLabel: z.string().optional(),
|
|
704
|
+
})
|
|
705
|
+
export type StorefrontHeroSpecProps = z.infer<typeof storefrontHeroPropsSchema>
|
|
706
|
+
|
|
436
707
|
export const faqItemSchema = z.object({
|
|
437
708
|
value: z.string(),
|
|
438
709
|
question: z.string(),
|
|
@@ -457,6 +728,129 @@ export const ctaSection1PropsSchema = z.object({
|
|
|
457
728
|
})
|
|
458
729
|
export type CtaSection1SpecProps = z.infer<typeof ctaSection1PropsSchema>
|
|
459
730
|
|
|
731
|
+
/**
|
|
732
|
+
* Serializable contract for the canonical `Feature` benefits section. The
|
|
733
|
+
* item `icon` is a Lucide icon NAME (e.g. `'Zap'`) that the registry resolves
|
|
734
|
+
* to a component at the seam; the React-only callbacks (`onCtaClick`,
|
|
735
|
+
* `onLearnMore`) are intentionally excluded — the catalog adapter binds them.
|
|
736
|
+
*/
|
|
737
|
+
export const featureItemSpecSchema = z.object({
|
|
738
|
+
id: z.string(),
|
|
739
|
+
title: z.string(),
|
|
740
|
+
description: z.string(),
|
|
741
|
+
icon: z.string(),
|
|
742
|
+
})
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* `cards` branch: the card grid never owns an image. The presentation is
|
|
746
|
+
* optional so an omitted value resolves to `cards`.
|
|
747
|
+
*/
|
|
748
|
+
export const featureCardsSpecSchema = z.object({
|
|
749
|
+
items: z.array(featureItemSpecSchema),
|
|
750
|
+
presentation: z.literal('cards').optional(),
|
|
751
|
+
badge: z.string().optional(),
|
|
752
|
+
title: z.string().optional(),
|
|
753
|
+
description: z.string().optional(),
|
|
754
|
+
ctaLabel: z.string().optional(),
|
|
755
|
+
learnMoreLabel: z.string().optional(),
|
|
756
|
+
className: z.string().optional(),
|
|
757
|
+
})
|
|
758
|
+
export type FeatureCardsSpecProps = z.infer<typeof featureCardsSpecSchema>
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* `split` branch: the editorial image is mandatory and must carry a non-empty
|
|
762
|
+
* `src`. `alt` stays required so the caller decides whether the image is
|
|
763
|
+
* informative or decorative. `cards`-only chrome is intentionally absent.
|
|
764
|
+
*/
|
|
765
|
+
export const featureSplitSpecSchema = z.object({
|
|
766
|
+
items: z.array(featureItemSpecSchema),
|
|
767
|
+
presentation: z.literal('split'),
|
|
768
|
+
title: z.string().optional(),
|
|
769
|
+
description: z.string().optional(),
|
|
770
|
+
image: z.object({ src: z.string().trim().min(1), alt: z.string() }),
|
|
771
|
+
className: z.string().optional(),
|
|
772
|
+
})
|
|
773
|
+
export type FeatureSplitSpecProps = z.infer<typeof featureSplitSpecSchema>
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Serialized `Feature` union. The split branch is listed first so
|
|
777
|
+
* `presentation: 'split'` resolves deterministically; an omitted presentation
|
|
778
|
+
* falls through to `cards`. A split input without a non-empty image matches
|
|
779
|
+
* neither branch and fails to parse.
|
|
780
|
+
*/
|
|
781
|
+
export const featurePropsSchema = z.union([featureSplitSpecSchema, featureCardsSpecSchema])
|
|
782
|
+
export type FeatureSpecProps = z.infer<typeof featurePropsSchema>
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Canonical category contract for the consolidated `ProductCategory` block.
|
|
786
|
+
*
|
|
787
|
+
* `categories` is the canonical category projection (a `@thorprovider/types`
|
|
788
|
+
* `ProductCategory` subset): ids are canonical strings, optional fields are
|
|
789
|
+
* omitted rather than serialized as `""`, and there are no demo-only required
|
|
790
|
+
* fields (no required subtitle, sector icon enum, or Lucide component). `icon`
|
|
791
|
+
* is a plain, serializable icon-key string resolved by the block against a
|
|
792
|
+
* bounded map with a neutral fallback. The `presentation` value is a bounded
|
|
793
|
+
* structure switch, never a per-store fork. Callbacks are runtime props and are
|
|
794
|
+
* excluded here (see the component).
|
|
795
|
+
*/
|
|
796
|
+
export const productCategoryItemSchema = z.object({
|
|
797
|
+
id: z.string(),
|
|
798
|
+
handle: z.string().optional(),
|
|
799
|
+
name: z.string(),
|
|
800
|
+
description: z.string().optional(),
|
|
801
|
+
/** Optional real count; an unknown count is omitted, never fabricated as `0`. */
|
|
802
|
+
itemCount: z.number().optional(),
|
|
803
|
+
/** Omitted (never `""`) when the backend has no image. */
|
|
804
|
+
image: z.string().optional(),
|
|
805
|
+
trending: z.boolean().optional(),
|
|
806
|
+
/** Serializable icon key (e.g. `'shirt'`); unknown keys render a neutral fallback. */
|
|
807
|
+
icon: z.string().optional(),
|
|
808
|
+
subcategories: z.array(z.string()).optional(),
|
|
809
|
+
featured: z.boolean().optional(),
|
|
810
|
+
})
|
|
811
|
+
export type ProductCategoryItem = z.infer<typeof productCategoryItemSchema>
|
|
812
|
+
|
|
813
|
+
export const productCategoryPropsSchema = z.object({
|
|
814
|
+
categories: z.array(productCategoryItemSchema),
|
|
815
|
+
presentation: z.enum(['grid', 'icons', 'list']).optional(),
|
|
816
|
+
title: z.string().optional(),
|
|
817
|
+
description: z.string().optional(),
|
|
818
|
+
badge: z.string().optional(),
|
|
819
|
+
cta: ctaSchema.optional(),
|
|
820
|
+
/** Controlled search value; filtering is owned by the host. */
|
|
821
|
+
query: z.string().optional(),
|
|
822
|
+
searchPlaceholder: z.string().optional(),
|
|
823
|
+
searchLabel: z.string().optional(),
|
|
824
|
+
emptyLabel: z.string().optional(),
|
|
825
|
+
noResultsLabel: z.string().optional(),
|
|
826
|
+
browseLabel: z.string().optional(),
|
|
827
|
+
viewAllLabel: z.string().optional(),
|
|
828
|
+
trendingLabel: z.string().optional(),
|
|
829
|
+
featuredLabel: z.string().optional(),
|
|
830
|
+
itemsLabel: z.string().optional(),
|
|
831
|
+
imageFallback: z.string().optional(),
|
|
832
|
+
className: z.string().optional(),
|
|
833
|
+
})
|
|
834
|
+
export type ProductCategorySpecProps = z.infer<typeof productCategoryPropsSchema>
|
|
835
|
+
|
|
836
|
+
export const categoryCardPropsSchema = z.object({
|
|
837
|
+
category: productCategoryItemSchema,
|
|
838
|
+
presentation: z.enum(['grid', 'icons', 'list']).optional(),
|
|
839
|
+
browseLabel: z.string().optional(),
|
|
840
|
+
itemsLabel: z.string().optional(),
|
|
841
|
+
trendingLabel: z.string().optional(),
|
|
842
|
+
featuredLabel: z.string().optional(),
|
|
843
|
+
imageFallback: z.string().optional(),
|
|
844
|
+
})
|
|
845
|
+
export type CategoryCardSpecProps = z.infer<typeof categoryCardPropsSchema>
|
|
846
|
+
|
|
847
|
+
export const categoryGridPropsSchema = productCategoryPropsSchema.extend({
|
|
848
|
+
maxItems: z.number().int().positive().optional(),
|
|
849
|
+
loading: z.boolean().optional(),
|
|
850
|
+
skeletonCount: z.number().int().positive().optional(),
|
|
851
|
+
})
|
|
852
|
+
export type CategoryGridSpecProps = z.infer<typeof categoryGridPropsSchema>
|
|
853
|
+
|
|
460
854
|
// Pure monetary helpers, re-exported from the server-safe contracts entry so a
|
|
461
855
|
// host boundary can validate/format `Money` without importing the React entry.
|
|
462
856
|
export { isCompleteFiniteDecimal, isAvailableMoney, formatMoney } from './money'
|
package/src/ui/button-group.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { cva, type VariantProps } from "class-variance-authority"
|
|
|
2
2
|
import { cn } from "cn"
|
|
3
3
|
import { Slot } from "radix-ui"
|
|
4
4
|
|
|
5
|
-
import { Separator } from "
|
|
5
|
+
import { Separator } from "./separator"
|
|
6
6
|
|
|
7
7
|
const buttonGroupVariants = cva(
|
|
8
8
|
"flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
package/src/ui/carousel.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import useEmblaCarousel, {
|
|
|
7
7
|
} from "embla-carousel-react"
|
|
8
8
|
import { ArrowLeft, ArrowRight } from "lucide-react"
|
|
9
9
|
|
|
10
|
-
import { Button } from "
|
|
10
|
+
import { Button } from "./button"
|
|
11
11
|
|
|
12
12
|
type CarouselApi = UseEmblaCarouselType[1]
|
|
13
13
|
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
package/src/ui/dialog.tsx
CHANGED
package/src/ui/field.tsx
CHANGED
|
@@ -4,8 +4,8 @@ import { useMemo } from "react"
|
|
|
4
4
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
5
5
|
import { cn } from "cn"
|
|
6
6
|
|
|
7
|
-
import { Label } from "
|
|
8
|
-
import { Separator } from "
|
|
7
|
+
import { Label } from "./label"
|
|
8
|
+
import { Separator } from "./separator"
|
|
9
9
|
|
|
10
10
|
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
11
11
|
return (
|
package/src/ui/input-group.tsx
CHANGED
|
@@ -4,9 +4,9 @@ import * as React from "react"
|
|
|
4
4
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
5
5
|
import { cn } from "cn"
|
|
6
6
|
|
|
7
|
-
import { Button } from "
|
|
8
|
-
import { Input } from "
|
|
9
|
-
import { Textarea } from "
|
|
7
|
+
import { Button } from "./button"
|
|
8
|
+
import { Input } from "./input"
|
|
9
|
+
import { Textarea } from "./textarea"
|
|
10
10
|
|
|
11
11
|
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
12
12
|
return (
|
package/src/ui/pagination.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
MoreHorizontalIcon,
|
|
7
7
|
} from "lucide-react"
|
|
8
8
|
|
|
9
|
-
import { buttonVariants, type Button } from "
|
|
9
|
+
import { buttonVariants, type Button } from "./button"
|
|
10
10
|
|
|
11
11
|
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
|
|
12
12
|
return (
|
package/src/ui/sidebar.tsx
CHANGED
|
@@ -6,24 +6,24 @@ import { cn } from "cn"
|
|
|
6
6
|
import { PanelLeftIcon } from "lucide-react"
|
|
7
7
|
import { Slot } from "radix-ui"
|
|
8
8
|
|
|
9
|
-
import { useIsMobile } from "
|
|
10
|
-
import { Button } from "
|
|
11
|
-
import { Input } from "
|
|
12
|
-
import { Separator } from "
|
|
9
|
+
import { useIsMobile } from "../hooks/use-mobile"
|
|
10
|
+
import { Button } from "./button"
|
|
11
|
+
import { Input } from "./input"
|
|
12
|
+
import { Separator } from "./separator"
|
|
13
13
|
import {
|
|
14
14
|
Sheet,
|
|
15
15
|
SheetContent,
|
|
16
16
|
SheetDescription,
|
|
17
17
|
SheetHeader,
|
|
18
18
|
SheetTitle,
|
|
19
|
-
} from "
|
|
20
|
-
import { Skeleton } from "
|
|
19
|
+
} from "./sheet"
|
|
20
|
+
import { Skeleton } from "./skeleton"
|
|
21
21
|
import {
|
|
22
22
|
Tooltip,
|
|
23
23
|
TooltipContent,
|
|
24
24
|
TooltipProvider,
|
|
25
25
|
TooltipTrigger,
|
|
26
|
-
} from "
|
|
26
|
+
} from "./tooltip"
|
|
27
27
|
|
|
28
28
|
const SIDEBAR_COOKIE_NAME = "sidebar_state"
|
|
29
29
|
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
|
package/src/ui/toggle-group.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { type VariantProps } from "class-variance-authority"
|
|
|
5
5
|
import { cn } from "cn"
|
|
6
6
|
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui"
|
|
7
7
|
|
|
8
|
-
import { toggleVariants } from "
|
|
8
|
+
import { toggleVariants } from "./toggle"
|
|
9
9
|
|
|
10
10
|
const ToggleGroupContext = React.createContext<
|
|
11
11
|
VariantProps<typeof toggleVariants> & {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "./tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"noEmit": false,
|
|
5
|
+
"emitDeclarationOnly": true,
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"incremental": false
|
|
9
|
+
},
|
|
10
|
+
"include": ["src/**/*"],
|
|
11
|
+
"exclude": ["node_modules", "dist", "src/**/*.test.ts", "src/**/*.test.tsx"]
|
|
12
|
+
}
|
package/tsup.config.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { defineConfig } from 'tsup'
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
// Emit one module per source file (no bundling) so consumers can import a
|
|
5
|
+
// single block and bundle only what they import. `outbase: 'src'` preserves
|
|
6
|
+
// the source layout under dist/ (e.g. dist/blocks/.../navbar.mjs).
|
|
7
|
+
entry: ['src/**/*.ts', 'src/**/*.tsx', '!src/**/*.test.ts', '!src/**/*.test.tsx'],
|
|
8
8
|
format: ['cjs', 'esm'],
|
|
9
|
-
|
|
9
|
+
// Declarations are emitted per-file by `tsc -p tsconfig.build.json` (see the
|
|
10
|
+
// build script); tsup's bundled dts step OOMs with 170+ entries.
|
|
11
|
+
dts: false,
|
|
10
12
|
splitting: false,
|
|
11
13
|
sourcemap: true,
|
|
12
14
|
clean: true,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
bundle: false,
|
|
16
|
+
esbuildOptions(options) {
|
|
17
|
+
options.outbase = 'src'
|
|
18
|
+
}
|
|
15
19
|
})
|