webcake-storefront-mcp 1.20.0 → 1.21.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.
@@ -205,19 +205,19 @@ export const ELEMENT_ATTRS = {
205
205
  switch: { events: "none", notes: "Toggle; style width/height." },
206
206
  // ── commerce ──
207
207
  "grid-product": {
208
- specials: { displayStyle: "default | only_image | border.", original_price_position: "left | right.", products_per_load: "Products fetched per page/scroll (real default 36).", show_original_price: "Show the compare-at price (boolean).", show_discount_on_price: "Show a discount badge on the price (boolean).", show_quick_view: "Show a quick-view button on hover (boolean)." },
209
- config: { columns: "Products per row.", responsive: "autofit | fixed | custom.", item_show: "How many products to show.", image_ratio: "16/9|3/2|4/3|1/1|4/5|9/16|2/3|3/4 (designer templates use 4/5).", img_object_fit: "cover|contain|fill|stretch.", gap_column: "Column gap (real default 30).", gap_row: "Row gap (real default 15).", product_info_padding_y: "Vertical padding of the name/price block (px).", price_padding_y: "Vertical padding around the price (px).", product_info_alignment: "left|center|right.", productNameFont: "Product-name font family.", productNameFontSize: "Product-name font size (px).", productPriceFont: "Price font family.", productPriceFontSize: "Price font size (px).", productPriceFontWeight: "Price font weight (e.g. bold).", productOriginalPriceFontSize: "Compare-at price font size (px).", sizeThumbnail: "{ width, height } of the card image." },
208
+ specials: { displayStyle: "default | only_image | border.", original_price_position: "left | right.", products_per_load: "Products fetched per page/scroll (real range 8–36).", category_id: "Source products from a specific category id (else current category).", show_original_price: "Show the compare-at price (boolean).", show_discount_on_price: "Show a discount badge on the price (boolean).", show_quick_view: "Show a quick-view button on hover (boolean).", show_product_name: "Show the product name (boolean).", show_product_price: "Show the price (boolean).", show_rating: "Show the star rating (boolean).", load_rating: "Fetch ratings for the cards (boolean).", show_ribbon: "Show a ribbon/badge (boolean).", load_brand: "Fetch + show the brand (boolean).", load_category: "Fetch + show the category (boolean).", show_categories: "Show category labels (boolean).", on_hover: "Card hover effect: zoom | swap (swap to 2nd image).", randomDisplay: "Randomise product order (boolean).", typeLinkCategory: "Related-products source: similar_product | products_viewed.", plugins: "Extra card plugins [{name,type,icon}] (e.g. attribute templates, extra info)." },
209
+ config: { columns: "Products per row (real range 1–6).", responsive: "autofit | fixed | custom (fixed keeps the column count; custom collapses on mobile).", item_show: "How many products to show.", image_ratio: "INDUSTRY-DEPENDENT: 4/5 fashion · 2/3 kids · 3/4 food · 1/1 square (cosmetics/electronics). Also 16/9|3/2|4/3|9/16.", img_object_fit: "cover|contain|fill|stretch.", gap_column: "Column gap (real range 8–40).", gap_row: "Row gap (real range 0–40).", product_info_padding_y: "Vertical padding of the name/price block (px).", price_padding_y: "Vertical padding around the price (px).", product_info_alignment: "left|center|right.", productNameFont: "Product-name font family.", productNameFontSize: "Product-name font size (px, real 12–18).", productNameColor: "Product-name colour.", productNameHover: "Product-name hover colour.", productNamePaddingY: "Vertical padding of the name (px).", productPriceFont: "Price font family.", productPriceFontSize: "Price font size (px).", productPriceFontWeight: "Price font weight — bold across ALL surveyed templates.", productPriceColor: "Price colour (often a theme accent / var).", productOriginalPriceFontSize: "Compare-at price font size (px).", productOriginalPriceColor: "Compare-at price colour (muted grey).", sizeThumbnail: "{ width, height } of the card image." },
210
210
  events: "none",
211
211
  bindings: ["product::product_image", "product::product_name", "product::product_price"],
212
- notes: "Lists store products (self-renders image+name+price card). Requires a 'store' page / use_store. Configure columns + image_ratio (4/5 reads as a fashion card); the price/name fonts + show_* flags style the card.",
212
+ notes: "Lists store products (self-renders image+name+price card). Requires a 'store' page / use_store. Config is INDUSTRY-DEPENDENT (surveyed fashion/kids/cosmetics/food/electronics): only bold price + responsive collapse + show original/discount are near-universal; pick image_ratio/columns/gaps/fonts/colours to match the brand.",
213
213
  },
214
214
  "slider-product": { specials: { displayStyle: "default|only_image|border.", original_price_position: "left|right." }, config: { slideItems: "Visible products.", slideWidth: "Card width.", image_ratio: "Aspect ratio." }, events: "none", bindings: ["product::product_image", "product::product_name", "product::product_price"] },
215
- "product-gallery": { events: "none", notes: "Product detail image gallery (product page)." },
215
+ "product-gallery": { specials: { showNavigation: "Show the thumbnail strip / nav (boolean — real templates often false).", on_hover: "Hover effect on the main image (e.g. zoom)." }, config: { sizeThumbnail: "{ width, height } of the main image (real 500–1044).", image_ratio: "Main image ratio (often 'auto')." }, events: "none", notes: "Product detail image gallery (product page). Mostly just sizeThumbnail + showNavigation." },
216
216
  "product-image-carousel": { events: "none", notes: "Product image carousel (product page)." },
217
217
  "cart-items": { events: "none", bindings: ["cart_item::cart_item_image", "cart_item::cart_item_name", "cart_item::cart_item_price", "cart_item::cart_item_total_price", "cart_item::cart_item_prod_attr"], notes: "Cart line items (cart page). A repeater whose config.columns defines the per-row column template — real templates use [70px image, 1fr name, ~240px price, ~116px qty, ~240px total, 34px remove]." },
218
218
  "cart-icon": { specials: { svg: "Icon SVG (defaults to a bag icon; fill='currentColor' so it inherits style.color).", itemCount: "Badge count (0 placeholder)." }, config: { itemCountFontFamily: "Badge font family.", itemCountFontSize: "Badge font size (e.g. 11px).", itemCountColor: "Badge text colour.", itemCountBorderRadius: "Badge corner radius (50% = circle)." }, events: "click — opens cart. Real templates wrap it in a container with open_popup(mouseenter)/close_popup(mouseleave) for a mini-cart, plus a container with open_page→cart page." },
219
- "quantity-input": { events: "none", notes: "Quantity stepper (product/cart)." },
220
- attr: { events: "none", notes: "Product attribute selector (variations)." },
219
+ "quantity-input": { specials: { spinner: "Native spinner style: hide-spin (product/cart, the default) | circle (checkout).", showRightBtn: "Show the +/- buttons (boolean)." }, config: { textColor: "Quantity text colour." }, events: "none", notes: "Quantity stepper (product/cart). Defaults to spinner:'hide-spin'." },
220
+ attr: { specials: { attrName: "Attribute to show, or 'auto'.", autoAttrName: "Resolved attribute name when attrName='auto' (e.g. Màu sắc, Kích thước).", autoNamePriority: "Order when auto (1,2,3…).", attrPrimary: "This is the primary variation (boolean).", layout: "Swatch layout variant (1,4…).", defaultSelected: "Pre-select the first option (boolean)." }, config: { borderColorHover: "Swatch hover border colour." }, events: "none", notes: "Product attribute/variation selector (product page). Add one attr per variation axis (colour, size); attrName:'auto' lets it resolve from the product." },
221
221
  payment: { events: "none", notes: "Payment methods block (checkout)." },
222
222
  "delivery-method": { specials: { options: "[{type: delivery|store_pickup, name, active}]." }, events: "none" },
223
223
  "order-items": { events: "none", bindings: ["order_item::product_image", "order_item::product_name", "order_item::product_quantity", "order_item::product_attrs", "order_item::items_sum_up_price"], notes: "Order summary lines (checkout/thank-you). Repeater whose config.columns is the per-row template — real templates use [75px image, 1fr name, 95px price]." },
@@ -363,9 +363,13 @@ export const buildElementWithBreakpoint = (el, breakpoint) => {
363
363
  el.specials = Object.assign({}, el.specials || {}, customSpecials);
364
364
  delete el.runtime;
365
365
  };
366
- // Real designer-template grid-product defaults (mined from prod theme "Mode Féminine"):
367
- // the card self-renders image + name + price; these keys control its look. Callers may
368
- // override any of them via opts.config / opts.specials.
366
+ // grid-product card self-renders image + name + price. The defaults below are the keys that
367
+ // are near-UNIVERSAL across real designer templates (surveyed 5 industries fashion/kids/
368
+ // cosmetics/food/electronics): bold price, responsive collapse, show original/discount price,
369
+ // a neutral square image + medium gaps. INDUSTRY-DEPENDENT keys (image_ratio 4/5|2/3|3/4|1/1,
370
+ // font family/size, column count, exact gaps, productNameColor/productPriceColor) are
371
+ // intentionally NOT forced here — the caller / template sets them. Override via opts.config /
372
+ // opts.specials.
369
373
  export const createGridProduct = (opts = {}) => {
370
374
  const product = cloneDeep(SKELETON);
371
375
  product.id = 'GRID-PRODUCT-' + randomString(8);
@@ -377,23 +381,20 @@ export const createGridProduct = (opts = {}) => {
377
381
  };
378
382
  product.runtime.config = {
379
383
  columns: 4,
380
- image_ratio: '4/5',
384
+ image_ratio: '1/1',
381
385
  img_object_fit: 'cover',
382
- gap_column: 30,
383
- gap_row: 15,
384
- product_info_padding_y: 15,
386
+ gap_column: 24,
387
+ gap_row: 24,
388
+ product_info_padding_y: 12,
385
389
  price_padding_y: 5,
386
- productNameFontSize: 18,
387
- productPriceFontSize: 18,
388
390
  productPriceFontWeight: 'bold',
389
- productOriginalPriceFontSize: 18,
390
391
  responsive: 'custom',
391
392
  heightUnit: 'auto',
392
393
  ...(opts.config || {})
393
394
  };
394
395
  product.specials = {
395
396
  element_async: true,
396
- products_per_load: 36,
397
+ products_per_load: 12,
397
398
  show_original_price: true,
398
399
  show_discount_on_price: true,
399
400
  show_quick_view: false,
@@ -751,7 +752,8 @@ export const createQuantityInput = (opts = {}) => {
751
752
  ...opts.style
752
753
  };
753
754
  input.runtime.config = opts.config || {};
754
- input.specials = opts.specials || {};
755
+ // Every surveyed template hides the native number spinner on product/cart steppers.
756
+ input.specials = { spinner: 'hide-spin', ...(opts.specials || {}) };
755
757
  if (opts.breakpoint) {
756
758
  buildElementWithBreakpoint(input, opts.breakpoint);
757
759
  }
@@ -87,13 +87,15 @@ A bare stack of default elements looks unfinished. Apply real styling:
87
87
  - HERO: prefer a section with a background image + an overlay heading/sub/button on top
88
88
  (set section_opts.style.background or a full-width image, then text centered), rather than a
89
89
  small image stacked above text.
90
- - PRODUCT GRID: grid-product SELF-RENDERS the image+name+price card; you mostly set
91
- \`opts.config\`: { columns:3-4, image_ratio:"4/5" (a tall fashion card; "1/1" for square),
92
- img_object_fit:"cover", gap_column:30, gap_row:15, product_info_padding_y:15,
93
- productNameFontSize:18, productPriceFontSize:18, productPriceFontWeight:"bold" } and
94
- \`opts.specials\`: { products_per_load:36, show_original_price:true, show_discount_on_price:true }.
95
- (These are the real designer-template defaults the factory now ships them, so a bare
96
- grid-product already looks right; there are NO cardBorderRadius/cardBoxShadow keys.)
90
+ - PRODUCT GRID: grid-product SELF-RENDERS the image+name+price card. Its look is
91
+ INDUSTRY-DEPENDENT (surveyed fashion/kids/cosmetics/food/electronics) only \`bold price\`,
92
+ \`responsive\` collapse and \`show_original_price/show_discount_on_price\` are near-universal;
93
+ the factory ships those + neutral defaults (columns 4, image_ratio "1/1", gap 24). Tune per
94
+ brand via \`opts.config\`: { columns:3-6, image_ratio:"4/5"|"2/3"|"3/4"|"1/1", img_object_fit:"cover",
95
+ gap_column:8-40, gap_row, product_info_alignment:"center"?, productNameColor, productPriceColor }
96
+ and \`opts.specials\`: { products_per_load:8-36, on_hover:"zoom"|"swap", show_rating, show_ribbon }.
97
+ (There are NO cardBorderRadius/cardBoxShadow keys.) For variations use \`attr\` elements
98
+ (attrName:"auto"); steppers are \`quantity-input\` (defaults spinner:"hide-spin").
97
99
  - BRAND COLOURS: reuse var(--color_00) (text), and an accent (var(--color_02)/var(--color_03))
98
100
  for buttons, prices, highlights — consistent accent = looks intentional.
99
101
  - IMAGES: must be WebCake-CDN urls (search_images cdn_url / upload_images), else they won't show.
@@ -1,4 +1,11 @@
1
1
  [
2
+ {
3
+ "v": "1.21.0",
4
+ "d": "25/06/2026",
5
+ "type": "Changed",
6
+ "en": "The grid-product factory now ships cross-industry neutral defaults (image_ratio:\"1/1\", gap_column/gap_row 24, products_per_load 12) instead of the…",
7
+ "vi": "Factory grid-product nay sử dụng các giá trị mặc định trung lập đa ngành (image_ratio:\"1/1\", gap_column/gap_row 24, products_per_load 12) thay vì…"
8
+ },
2
9
  {
3
10
  "v": "1.20.0",
4
11
  "d": "25/06/2026",
@@ -33,12 +40,5 @@
33
40
  "type": "Added",
34
41
  "en": "New get_intake_guide tool returns a step-by-step questionnaire and recommended build flow (create_site → products → build_page → global sections →…",
35
42
  "vi": "Tool mới get_intake_guide trả về bảng câu hỏi từng bước và quy trình build được khuyến nghị (create_site → sản phẩm → build_page → global sections →…"
36
- },
37
- {
38
- "v": "1.17.1",
39
- "d": "25/06/2026",
40
- "type": "Changed",
41
- "en": "get_http_function and get_site_custom_code now include a \"File / media uploads\" section in the embedded HTTP function guide, documenting three ways…",
42
- "vi": "get_http_function và get_site_custom_code nay bổ sung mục \"File / media uploads\" vào hướng dẫn HTTP function nhúng sẵn, tài liệu hóa ba cách tải…"
43
43
  }
44
44
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webcake-storefront-mcp",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "MCP server for the WebCake/StoreCake storefront builder — page CRUD, page authoring, products, orders, and more",
5
5
  "mcpName": "io.github.vuluu2k/webcake-storefront-mcp",
6
6
  "license": "MIT",