Repository navigation
Update storefront component design using Opus - #1515
Conversation
Catalog cards get square images, a Sale badge and compare-at price, and no description. The product page uses option buttons (a select above eight values), crosses out sold-out values, caps a quantity stepper at stock, and labels add with the total or the next missing option. The cart drawer shows the count, one-line options, a checkout-note row and Continue shopping, and CartButton becomes an icon with a count badge. Swatches are supported through a getSwatch provider prop, off by default. RelatedProducts is a new optional component. Sold-out marking uses SKU attribute value names when the server returns them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each SKU in the product details response now carries its attribute value names, so a client can tell which option values are sold out given the other selections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: e55a25c The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…r SKU The stepper now works before options are chosen, so resetting the quantity on every selection change silently dropped a quantity the shopper set. It is kept; a quantity above the new SKU's stock shows the quantity error. A struck-through compare-at price could pair the cheapest SKU's price with another SKU's compare-at price. The product page now strikes through a starting compare-at price only when the cheapest SKUs share it, and cards only for a single price. The Sale badge is unchanged. The changeset notes the quantity and status changes for custom layouts, and card swatch text keeps acronyms in attribute labels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wesleycole
left a comment
There was a problem hiding this comment.
Approving with one non-blocking follow-up: isProductOnSale() in packages/commerce-storefront/src/product-card.tsx:243–245 compares product-wide minimum price and minimum compare-at price, which may belong to different SKUs. For example, a $10 SKU without a compare-at price plus a $20 SKU with a $20 compare-at price incorrectly receives a Sale badge. The reverse can hide a real discount when the cheapest SKU has an equal compare-at price. This affects catalog/related-product cards and the product page before selection. Please consider determining sale status from paired prices on individual SKUs, with a conservative fallback for incomplete data. Two targeted regression tests reproduced both cases.
Validation: storefront build, all 121 existing storefront tests, storefront typecheck, and all 256 server tests passed.
The badge compared the product's lowest price with its lowest compare-at price, which can belong to different SKUs: a $10 SKU without a compare-at price beside a $20 SKU at a $20 compare-at price was badged, and a real markdown on a pricier SKU was missed when the cheapest SKU's compare-at price equaled its price. With every SKU's price loaded, as on the product page, the badge shows when some SKU's compare-at price is above that SKU's price. Without them, as in the catalog list, it shows only when the lowest compare-at price is above the highest price, which guarantees a marked-down SKU. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Gives the packaged storefront components a cleaner default look that reads well on light and dark host pages without configuration. The design is pretty similar, but it adds a few features and cleans it up.
CartContinueShoppingpart and a new empty state.CartButtonis now a bag icon with a count badge.getSwatchprovider prop, and a newRelatedProductscomponent.--commerce-sale/--commerce-on-saletheme properties. Muted text, lines and outlined or disabled controls derive from the inherited text color, so they work on dark pages.gd-commerce-serverreturns each SKU's attribute value names, which sold-out marking uses. It's a separate commit. The storefront treats the field as optional: without it, or when the SKU list is truncated, no value is marked.Review fixes: choosing an option no longer resets a quantity the shopper already set, and the Sale badge and struck-through compare-at price now compare each SKU's price with its own compare-at price.
Changeset
storefront-default-design.md(gd-commerce-storefront minor) andsku-attribute-values.md(gd-commerce-server minor)Test Plan
pnpm --filter @godaddy/gd-commerce-storefront build,test(123 passing, including a newdefault-design.test.tsx),lintandtypecheckpnpm --filter @godaddy/gd-commerce-server test(256 passing) andlint