create-cartbase 0.1.6 → 0.1.7
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/README.md +13 -8
- package/dist/index.js +28 -20
- package/package.json +21 -21
- package/template/app/AGENTS.md +29 -0
- package/template/app/CLAUDE.md +19 -8
- package/template/app/docs/BUILD-A-STOREFRONT.md +233 -226
- package/template/app/docs/README.md +1 -0
- package/template/app/docs/deploy.md +15 -10
- package/template/app/docs/platform.md +1 -1
- package/template/app/docs/store.md +47 -0
- package/template/app/docs/variables.md +3 -3
- package/template/app/next.config.ts +10 -14
- package/template/app/package.json +4 -3
- package/template/app/src/app/checkout/checkout-page-client.tsx +0 -20
- package/template/app/src/app/globals.css +1 -1
- package/template/app/src/app/layout.tsx +59 -18
- package/template/app/src/lib/config.ts +30 -21
- package/template/app/next-env.d.ts +0 -6
- package/template/app/smoke.mjs +0 -158
- package/template/app/src/app/checkout/mypos-demo-tab.tsx +0 -101
- package/template/app/src/app/gallery/[slug]/page.tsx +0 -172
- package/template/app/src/app/gallery/_components/specimens.tsx +0 -254
- package/template/app/src/app/gallery/_components/status.tsx +0 -47
- package/template/app/src/app/gallery/_lib/catalog.ts +0 -59
- package/template/app/src/app/gallery/_lib/registry.ts +0 -401
- package/template/app/src/app/gallery/design-system/page.tsx +0 -353
- package/template/app/src/app/gallery/layout.tsx +0 -83
- package/template/app/src/app/gallery/page.tsx +0 -81
- package/template/app/tsconfig.tsbuildinfo +0 -1
|
@@ -1,401 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The catalogue of everything the storefront library has, or has to have.
|
|
3
|
-
*
|
|
4
|
-
* This is the working board. Every entry has a permanent slug, so a component
|
|
5
|
-
* has an address you can be sent to: /gallery/hero, /gallery/product-card.
|
|
6
|
-
* That is the point — we pick one, open it, shape it, agree it, mark it done,
|
|
7
|
-
* and move to the next.
|
|
8
|
-
*
|
|
9
|
-
* Groups follow the STOREFRONT, not our folder names. A merchant thinks in
|
|
10
|
-
* "the product page", "the cart", "the sections I drop on the home page",
|
|
11
|
-
* never in "the products family barrel".
|
|
12
|
-
*
|
|
13
|
-
* Status is the truth of the sweep, and `missing` entries are as important as
|
|
14
|
-
* built ones: they are the sections the library still owes a merchant, and
|
|
15
|
-
* they are why this board doubles as the roadmap.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
export type Status =
|
|
19
|
-
/** Agreed with Alexander, values stripped to tokens, finished. */
|
|
20
|
-
| "done"
|
|
21
|
-
/** Code exists and renders, but we have never looked at it together. */
|
|
22
|
-
| "built"
|
|
23
|
-
/** Does not exist yet. Building it is the work. */
|
|
24
|
-
| "missing"
|
|
25
|
-
|
|
26
|
-
export type Entry = {
|
|
27
|
-
slug: string
|
|
28
|
-
name: string
|
|
29
|
-
status: Status
|
|
30
|
-
/** What it is, in the words we would use talking about it. */
|
|
31
|
-
summary: string
|
|
32
|
-
/** Where it lives, for when the answer is "open the file". */
|
|
33
|
-
source?: string
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export type Group = {
|
|
37
|
-
slug: string
|
|
38
|
-
name: string
|
|
39
|
-
blurb: string
|
|
40
|
-
entries: Entry[]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const GROUPS: Group[] = [
|
|
44
|
-
{
|
|
45
|
-
slug: "sections",
|
|
46
|
-
name: "Sections",
|
|
47
|
-
blurb:
|
|
48
|
-
"The blocks a merchant arranges to build a page. None of these exist yet — this is the biggest hole in the library and the reason a fresh install still looks like a catalogue rather than a shop.",
|
|
49
|
-
entries: [
|
|
50
|
-
{
|
|
51
|
-
slug: "hero",
|
|
52
|
-
name: "Hero",
|
|
53
|
-
status: "missing",
|
|
54
|
-
summary:
|
|
55
|
-
"The first screen. Image or video, a headline, one action. Every store has one and every store's is different, so this is the hardest one to get right and the most valuable.",
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
slug: "announcement-bar",
|
|
59
|
-
name: "Announcement bar",
|
|
60
|
-
status: "missing",
|
|
61
|
-
summary: "The thin strip above the header. Shipping promise, promotion, or nothing.",
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
slug: "featured-products",
|
|
65
|
-
name: "Featured products",
|
|
66
|
-
status: "missing",
|
|
67
|
-
summary:
|
|
68
|
-
"A hand-picked or automatic row of products on a page that is not the catalogue. Needs a data source the platform may not expose yet.",
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
slug: "featured-collection",
|
|
72
|
-
name: "Featured collection",
|
|
73
|
-
status: "missing",
|
|
74
|
-
summary: "One collection presented as a block, with its own image and copy.",
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
slug: "image-with-text",
|
|
78
|
-
name: "Image with text",
|
|
79
|
-
status: "missing",
|
|
80
|
-
summary: "The workhorse editorial block. Picture one side, words the other, both orders.",
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
slug: "rich-text",
|
|
84
|
-
name: "Rich text",
|
|
85
|
-
status: "missing",
|
|
86
|
-
summary: "A block of formatted words on its own. The About paragraph, the shipping note.",
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
slug: "social-proof",
|
|
90
|
-
name: "Social proof",
|
|
91
|
-
status: "missing",
|
|
92
|
-
summary: "Review summary, star rating, press logos, customer photos.",
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
slug: "newsletter",
|
|
96
|
-
name: "Newsletter signup",
|
|
97
|
-
status: "missing",
|
|
98
|
-
summary: "Email capture. Needs a real destination, which is a platform question, not a design one.",
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
slug: "faq",
|
|
102
|
-
name: "FAQ",
|
|
103
|
-
status: "missing",
|
|
104
|
-
summary: "Questions and answers, collapsible. The accordion primitive exists; the section does not.",
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
slug: "footer",
|
|
108
|
-
name: "Footer",
|
|
109
|
-
status: "missing",
|
|
110
|
-
summary:
|
|
111
|
-
"Menus, payment badges, legal. Today the example app hand-rolls one, which means every merchant would too.",
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
slug: "header",
|
|
115
|
-
name: "Header and navigation",
|
|
116
|
-
status: "missing",
|
|
117
|
-
summary:
|
|
118
|
-
"Logo, menu, search, cart. Also hand-rolled in the example app today. Probably the second thing to build after the hero.",
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
slug: "listing",
|
|
124
|
-
name: "Catalogue and listing",
|
|
125
|
-
blurb: "Everything between the home page and a single product.",
|
|
126
|
-
entries: [
|
|
127
|
-
{
|
|
128
|
-
slug: "product-card",
|
|
129
|
-
name: "Product card",
|
|
130
|
-
status: "built",
|
|
131
|
-
summary:
|
|
132
|
-
"The one card. Search results, collections and related rails all render it, so a mistake here is a mistake in five places.",
|
|
133
|
-
source: "products/product-preview.tsx",
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
slug: "thumbnail",
|
|
137
|
-
name: "Thumbnail",
|
|
138
|
-
status: "built",
|
|
139
|
-
summary: "Product imagery at four ratios, plus the fallback when there is no image.",
|
|
140
|
-
source: "products/thumbnail.tsx",
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
slug: "preview-price",
|
|
144
|
-
name: "Price on a card",
|
|
145
|
-
status: "built",
|
|
146
|
-
summary: "The cheapest price, and the struck-through original when reduced.",
|
|
147
|
-
source: "products/preview-price.tsx",
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
slug: "product-grid",
|
|
151
|
-
name: "Product grid",
|
|
152
|
-
status: "built",
|
|
153
|
-
summary:
|
|
154
|
-
"Not a component, an arrangement. Cards with different title lengths sitting together is the real test of the card.",
|
|
155
|
-
source: "store/store-template.tsx",
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
slug: "sort-select",
|
|
159
|
-
name: "Sort control",
|
|
160
|
-
status: "built",
|
|
161
|
-
summary: "Newest, price up, price down.",
|
|
162
|
-
source: "store/sort-select.tsx",
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
slug: "pagination",
|
|
166
|
-
name: "Pagination",
|
|
167
|
-
status: "built",
|
|
168
|
-
summary: "Page through a long catalogue.",
|
|
169
|
-
source: "store/pagination.tsx",
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
slug: "collection-page",
|
|
173
|
-
name: "Collection page",
|
|
174
|
-
status: "built",
|
|
175
|
-
summary: "A collection's own page: its title, its description, its products.",
|
|
176
|
-
source: "store/collection-template.tsx",
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
slug: "category-page",
|
|
180
|
-
name: "Category page",
|
|
181
|
-
status: "built",
|
|
182
|
-
summary: "The same for a category.",
|
|
183
|
-
source: "store/category-template.tsx",
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
slug: "grid-skeleton",
|
|
187
|
-
name: "Loading grid",
|
|
188
|
-
status: "built",
|
|
189
|
-
summary: "What the catalogue looks like before it arrives.",
|
|
190
|
-
source: "store/skeleton-product-grid.tsx",
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
slug: "filters",
|
|
194
|
-
name: "Filters",
|
|
195
|
-
status: "missing",
|
|
196
|
-
summary:
|
|
197
|
-
"Filter by size, colour, price, availability. Does not exist, and no real clothing store ships without it.",
|
|
198
|
-
},
|
|
199
|
-
],
|
|
200
|
-
},
|
|
201
|
-
{
|
|
202
|
-
slug: "product-page",
|
|
203
|
-
name: "Product page",
|
|
204
|
-
blurb: "The page that sells. Every part of it is a separate decision.",
|
|
205
|
-
entries: [
|
|
206
|
-
{
|
|
207
|
-
slug: "product-page-template",
|
|
208
|
-
name: "The whole page",
|
|
209
|
-
status: "built",
|
|
210
|
-
summary: "The assembled product page, which is what a merchant sees first.",
|
|
211
|
-
source: "products/product-template.tsx",
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
slug: "image-gallery",
|
|
215
|
-
name: "Image gallery",
|
|
216
|
-
status: "built",
|
|
217
|
-
summary: "The image column. Has to hold one photo and eight equally well.",
|
|
218
|
-
source: "products/image-gallery.tsx",
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
slug: "product-info",
|
|
222
|
-
name: "Title and description",
|
|
223
|
-
status: "built",
|
|
224
|
-
summary: "Name, subtitle, collection, description.",
|
|
225
|
-
source: "products/product-info.tsx",
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
slug: "product-price",
|
|
229
|
-
name: "Price",
|
|
230
|
-
status: "built",
|
|
231
|
-
summary: "The price on the page itself, including the reduced state.",
|
|
232
|
-
source: "products/product-price.tsx",
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
slug: "option-select",
|
|
236
|
-
name: "Option picker",
|
|
237
|
-
status: "built",
|
|
238
|
-
summary:
|
|
239
|
-
"Size, colour, whatever the merchant defined. Breaks first when a product has twelve variants.",
|
|
240
|
-
source: "products/option-select.tsx",
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
slug: "product-actions",
|
|
244
|
-
name: "Add to cart",
|
|
245
|
-
status: "built",
|
|
246
|
-
summary: "The button that earns the money, plus its sold-out and adding states.",
|
|
247
|
-
source: "products/product-actions.tsx",
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
slug: "purchase-options",
|
|
251
|
-
name: "One-time or subscription",
|
|
252
|
-
status: "built",
|
|
253
|
-
summary: "Buy once, or on a repeating plan.",
|
|
254
|
-
source: "products/purchase-options.tsx",
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
slug: "product-tabs",
|
|
258
|
-
name: "Details tabs",
|
|
259
|
-
status: "built",
|
|
260
|
-
summary: "Materials, shipping, returns.",
|
|
261
|
-
source: "products/product-tabs.tsx",
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
slug: "mobile-actions",
|
|
265
|
-
name: "Mobile buy bar",
|
|
266
|
-
status: "built",
|
|
267
|
-
summary: "The sticky bar on a phone. Most of your traffic will see this and not the button above.",
|
|
268
|
-
source: "products/mobile-actions.tsx",
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
slug: "related-products",
|
|
272
|
-
name: "Related products",
|
|
273
|
-
status: "built",
|
|
274
|
-
summary: "The rail under the fold.",
|
|
275
|
-
source: "products/related-products.tsx",
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
slug: "stock-state",
|
|
279
|
-
name: "Availability",
|
|
280
|
-
status: "missing",
|
|
281
|
-
summary:
|
|
282
|
-
"Nothing today tells a customer a product is sold out before they press the button. Found while building the gallery.",
|
|
283
|
-
},
|
|
284
|
-
],
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
slug: "cart",
|
|
288
|
-
name: "Cart",
|
|
289
|
-
blurb:
|
|
290
|
-
"Twenty-one pieces, the largest family in the library and the one with the most merchandising in it.",
|
|
291
|
-
entries: [
|
|
292
|
-
{ slug: "cart-drawer", name: "Cart drawer", status: "built", summary: "The whole slide-out cart.", source: "cart-drawer/cart-drawer.tsx" },
|
|
293
|
-
{ slug: "cart-item", name: "Cart line", status: "built", summary: "One product in the cart, with its variant and quantity.", source: "cart-drawer/item/index.tsx" },
|
|
294
|
-
{ slug: "cart-empty", name: "Empty cart", status: "built", summary: "What an empty cart says. A wasted screen in most stores.", source: "cart-drawer/empty.tsx" },
|
|
295
|
-
{ slug: "cart-summary", name: "Totals breakdown", status: "built", summary: "Subtotal, shipping, tax, discount, total.", source: "cart-drawer/summary-breakdown.tsx" },
|
|
296
|
-
{ slug: "cart-cross-sell", name: "Cross-sell", status: "built", summary: "Carousel and sidebar variants of add-this-too.", source: "cart-drawer/cross-sell-carousel.tsx" },
|
|
297
|
-
{ slug: "cart-free-gift", name: "Free gift", status: "built", summary: "The gift unlocked by spend.", source: "cart-drawer/free-gift.tsx" },
|
|
298
|
-
{ slug: "cart-tiered-progress", name: "Spend progress", status: "built", summary: "Add 20 EUR more for free shipping.", source: "cart-drawer/tiered-progress.tsx" },
|
|
299
|
-
{ slug: "cart-gift-wrap", name: "Gift wrap", status: "built", summary: "The paid wrapping option.", source: "cart-drawer/gift-wrap.tsx" },
|
|
300
|
-
{ slug: "cart-notes", name: "Order note", status: "built", summary: "The free-text box.", source: "cart-drawer/notes.tsx" },
|
|
301
|
-
{ slug: "cart-rewards", name: "Loyalty points", status: "built", summary: "Points earned on this order.", source: "cart-drawer/rewards-points.tsx" },
|
|
302
|
-
{ slug: "cart-payment-badges", name: "Payment badges", status: "built", summary: "The card logos that reassure.", source: "cart-drawer/payment-badges.tsx" },
|
|
303
|
-
{ slug: "cart-promo-banner", name: "Promo banner", status: "built", summary: "The message strip inside the cart.", source: "cart-drawer/promo-banner.tsx" },
|
|
304
|
-
{ slug: "cart-sticky-footer", name: "Checkout bar", status: "built", summary: "The pinned total and checkout button.", source: "cart-drawer/sticky-footer.tsx" },
|
|
305
|
-
],
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
slug: "checkout",
|
|
309
|
-
name: "Checkout",
|
|
310
|
-
blurb:
|
|
311
|
-
"Twenty pieces. Mostly locked, because this is where money moves and a merchant editing it breaks selling.",
|
|
312
|
-
entries: [
|
|
313
|
-
{ slug: "checkout-page", name: "The whole checkout", status: "built", summary: "Address, delivery, payment, review.", source: "checkout/checkout-client.tsx" },
|
|
314
|
-
{ slug: "address-form", name: "Address form", status: "built", summary: "The longest form in the product.", source: "checkout/address-form.tsx" },
|
|
315
|
-
{ slug: "shipping-methods", name: "Delivery choices", status: "built", summary: "The rates a customer picks from.", source: "checkout/shipping-method-list.tsx" },
|
|
316
|
-
{ slug: "payment-methods", name: "Payment choices", status: "built", summary: "Cards, offline tenders, and their fees.", source: "checkout/payment-method-list.tsx" },
|
|
317
|
-
{ slug: "order-summary", name: "Order summary", status: "built", summary: "What you are about to buy, priced.", source: "checkout/order-summary.tsx" },
|
|
318
|
-
{ slug: "discount-section", name: "Discount code", status: "built", summary: "The box, and what a wrong code says.", source: "checkout/discount-section.tsx" },
|
|
319
|
-
{ slug: "gift-card-section", name: "Gift card", status: "built", summary: "Redeeming a gift card at checkout.", source: "checkout/gift-card-section.tsx" },
|
|
320
|
-
{ slug: "payment-button", name: "Pay button", status: "built", summary: "The last button in the funnel.", source: "checkout/payment-button.tsx" },
|
|
321
|
-
{ slug: "locker-selectors", name: "Locker and office pickers", status: "built", summary: "BoxNow and Econt pickup points, on a map.", source: "checkout/boxnow-locker-selector.tsx" },
|
|
322
|
-
{ slug: "company-details", name: "Company details", status: "built", summary: "VAT number and company name for business buyers.", source: "checkout/company-details.tsx" },
|
|
323
|
-
{ slug: "checkout-errors", name: "Error states", status: "built", summary: "What a declined card, a bad address and a lost session look like.", source: "checkout/error-message.tsx" },
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
slug: "order",
|
|
328
|
-
name: "After the order",
|
|
329
|
-
blurb: "The thank-you page and the order record. The part everyone forgets to design.",
|
|
330
|
-
entries: [
|
|
331
|
-
{ slug: "order-confirmation", name: "Thank-you page", status: "built", summary: "The whole confirmation screen.", source: "order/order-completed-template.tsx" },
|
|
332
|
-
{ slug: "order-header", name: "Confirmation header", status: "built", summary: "Order number, date, the reassurance line.", source: "order/order-confirmation-header.tsx" },
|
|
333
|
-
{ slug: "order-items", name: "What you bought", status: "built", summary: "The line items on the confirmation.", source: "order/order-items-list.tsx" },
|
|
334
|
-
{ slug: "order-totals", name: "What you paid", status: "built", summary: "The money breakdown.", source: "order/order-totals.tsx" },
|
|
335
|
-
{ slug: "order-address", name: "Where it goes", status: "built", summary: "Shipping and billing addresses.", source: "order/order-address-card.tsx" },
|
|
336
|
-
{ slug: "order-delivery", name: "Delivery", status: "built", summary: "Carrier, tracking, expected date.", source: "order/order-delivery-card.tsx" },
|
|
337
|
-
{ slug: "order-payment", name: "How you paid", status: "built", summary: "Method and status.", source: "order/order-payment-card.tsx" },
|
|
338
|
-
{ slug: "order-timeline", name: "Order timeline", status: "built", summary: "What has happened to this order so far.", source: "order/order-timeline.tsx" },
|
|
339
|
-
{ slug: "order-help", name: "Need help", status: "built", summary: "Contact and returns.", source: "order/order-help-section.tsx" },
|
|
340
|
-
],
|
|
341
|
-
},
|
|
342
|
-
{
|
|
343
|
-
slug: "reviews",
|
|
344
|
-
name: "Reviews",
|
|
345
|
-
blurb: "Stars, distribution, the writing flow and the photo lightbox.",
|
|
346
|
-
entries: [
|
|
347
|
-
{ slug: "review-widget", name: "Reviews block", status: "built", summary: "The whole reviews section on a product page.", source: "reviews-ui/review-widget.tsx" },
|
|
348
|
-
{ slug: "star-badge", name: "Stars", status: "built", summary: "The rating badge, the star row, the distribution bars.", source: "reviews-ui/star-badge.tsx" },
|
|
349
|
-
{ slug: "review-list", name: "Review list", status: "built", summary: "Written reviews, with the photo lightbox.", source: "reviews-ui/review-list.tsx" },
|
|
350
|
-
{ slug: "review-wizard", name: "Write a review", status: "built", summary: "The flow a customer goes through, including photo upload.", source: "reviews-ui/review-wizard.tsx" },
|
|
351
|
-
],
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
slug: "global",
|
|
355
|
-
name: "Global",
|
|
356
|
-
blurb: "Things that appear on every page regardless of what the page is.",
|
|
357
|
-
entries: [
|
|
358
|
-
{ slug: "cart-button", name: "Cart button", status: "built", summary: "The header cart with its count.", source: "common/cart-button-client.tsx" },
|
|
359
|
-
{ slug: "country-select", name: "Country picker", status: "built", summary: "Region switching.", source: "common/country-select.tsx" },
|
|
360
|
-
{ slug: "language-select", name: "Language picker", status: "built", summary: "Locale switching.", source: "common/language-select.tsx" },
|
|
361
|
-
{ slug: "consent-banner", name: "Cookie consent", status: "built", summary: "The banner and its settings link. Legally required, visually hated.", source: "tracking/consent-banner.tsx" },
|
|
362
|
-
{ slug: "skeletons", name: "Loading states", status: "built", summary: "What every surface looks like before its data lands.", source: "common/skeleton.tsx" },
|
|
363
|
-
{ slug: "search", name: "Search", status: "missing", summary: "There is a search page, but no search component a merchant can place." },
|
|
364
|
-
],
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
slug: "primitives",
|
|
368
|
-
name: "Primitives",
|
|
369
|
-
blurb:
|
|
370
|
-
"The smallest components, the ones every other component is built from. Get the button wrong and everything above inherits the mistake. These are components, not tokens — the tokens live in the design system, which is a layer below all of this.",
|
|
371
|
-
entries: [
|
|
372
|
-
{ slug: "button", name: "Button", status: "built", summary: "Every variant and size. Add-to-cart is this component.", source: "primitives/ui/button.tsx" },
|
|
373
|
-
{ slug: "input", name: "Input", status: "built", summary: "Checkout is mostly this, repeated.", source: "primitives/ui/input.tsx" },
|
|
374
|
-
{ slug: "select", name: "Select", status: "built", summary: "The dropdown.", source: "primitives/ui/select.tsx" },
|
|
375
|
-
{ slug: "field", name: "Field", status: "built", summary: "Label, input, error, in one.", source: "primitives/field.tsx" },
|
|
376
|
-
{ slug: "tabs", name: "Tabs", status: "built", summary: "Used by the product details.", source: "primitives/ui/tabs.tsx" },
|
|
377
|
-
{ slug: "accordion", name: "Accordion", status: "built", summary: "Collapsible rows. The FAQ section will be built on this.", source: "primitives/ui/accordion.tsx" },
|
|
378
|
-
{ slug: "dialog", name: "Dialog", status: "built", summary: "Modal windows.", source: "primitives/ui/dialog.tsx" },
|
|
379
|
-
{ slug: "sheet", name: "Sheet", status: "built", summary: "The slide-in panel the cart drawer uses.", source: "primitives/ui/sheet.tsx" },
|
|
380
|
-
{ slug: "popover", name: "Popover", status: "built", summary: "Small floating panels.", source: "primitives/ui/popover.tsx" },
|
|
381
|
-
],
|
|
382
|
-
},
|
|
383
|
-
]
|
|
384
|
-
|
|
385
|
-
export const ALL_ENTRIES: Array<Entry & { group: Group }> = GROUPS.flatMap((group) =>
|
|
386
|
-
group.entries.map((entry) => ({ ...entry, group }))
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
export function findEntry(slug: string) {
|
|
390
|
-
return ALL_ENTRIES.find((e) => e.slug === slug) ?? null
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
export function counts() {
|
|
394
|
-
const all = ALL_ENTRIES
|
|
395
|
-
return {
|
|
396
|
-
total: all.length,
|
|
397
|
-
done: all.filter((e) => e.status === "done").length,
|
|
398
|
-
built: all.filter((e) => e.status === "built").length,
|
|
399
|
-
missing: all.filter((e) => e.status === "missing").length,
|
|
400
|
-
}
|
|
401
|
-
}
|