webcake-storefront-mcp 1.23.0 → 1.25.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/dist/builder/attributes.js +55 -33
- package/dist/changelog.json +14 -14
- package/package.json +1 -1
|
@@ -22,6 +22,8 @@ export const SHARED_SPECIALS = {
|
|
|
22
22
|
custom_css: "Raw CSS scoped to this element.",
|
|
23
23
|
element_async: "Mark the element async/lazy (advanced — usually leave unset).",
|
|
24
24
|
event_name_custom: "Custom analytics event name fired on interaction.",
|
|
25
|
+
tabIndex: "Bind this element to a tab item (TAB-ITEM-…) so a tabs element shows/hides it.",
|
|
26
|
+
text_animation_type: "Entrance animation for the element's text (none|…).",
|
|
25
27
|
};
|
|
26
28
|
// Generic layout keys every node's runtime.config may carry (documented in the build
|
|
27
29
|
// guide); listed here so describeAttributes can flag them as 'generic, not element-specific'.
|
|
@@ -131,7 +133,8 @@ export const ELEMENT_ATTRS = {
|
|
|
131
133
|
notes: "Set specials.text (HTML) + specials.tag. Style via runtime.style (color, fontSize, fontWeight, textAlign, lineHeight, letterSpacing).",
|
|
132
134
|
},
|
|
133
135
|
"text-dataset": {
|
|
134
|
-
|
|
136
|
+
specials: { tag: "Semantic tag (h1..h6/p) — set 'h1' for the product/post title." },
|
|
137
|
+
config: { hover_color: "Text colour on hover." }, events: "none",
|
|
135
138
|
bindings: ["product::product_name", "product::product_price", "cart_item::cart_item_name", "cart_item::cart_item_price", "order_item::product_name", "customer_address::full_name"],
|
|
136
139
|
notes: "Text bound to live data — set bindings[].target to a source::field; no static specials.text.",
|
|
137
140
|
},
|
|
@@ -147,33 +150,35 @@ export const ELEMENT_ATTRS = {
|
|
|
147
150
|
notes: "Image bound to live data — set bindings[].target; no static src.",
|
|
148
151
|
},
|
|
149
152
|
video: {
|
|
150
|
-
specials: { src: "Video URL.", thumbnail: "Poster image URL.", time: "Duration label (e.g. '10.0s').", type: "Source type (
|
|
153
|
+
specials: { src: "Video URL.", thumbnail: "Poster image URL.", time: "Duration label (e.g. '10.0s').", type: "Source type (store|youtube).", id: "YouTube/provider video id.", autoplay: "Auto-play (boolean).", loop: "Loop (boolean).", showControl: "Show player controls (boolean)." },
|
|
154
|
+
config: { ratio: "Aspect ratio (e.g. 0.5625 = 16/9).", src: "Video URL (mirror)." },
|
|
151
155
|
events: "none",
|
|
152
156
|
},
|
|
153
|
-
"video-dataset": { events: "none", bindings: ["lesson::lesson_video"], notes: "Video bound to a dataset field." },
|
|
157
|
+
"video-dataset": { specials: { autoRotateInMobile: "Rotate to landscape on mobile (boolean).", show_list_video_lesson: "Show the lesson playlist (boolean).", show_next_video_lesson: "Show the next-lesson button (boolean)." }, events: "none", bindings: ["lesson::lesson_video"], notes: "Video bound to a dataset field (course lesson video)." },
|
|
154
158
|
rectangle: {
|
|
155
159
|
specials: { shapeType: "Shape kind.", custom_css: "Raw CSS for the shape." },
|
|
156
|
-
config: { mask: "Mask
|
|
160
|
+
config: { mask: "Mask SVG/shape (clips the box into an icon).", maskId: "Mask reference.", custom_mask: "Custom mask SVG markup.", fixedPosition: "Pin/float the shape (bottom_right|…) — e.g. a floating badge.", animation: "Entrance animation." },
|
|
157
161
|
events: "click, hover — often used as a clickable card/background.",
|
|
158
162
|
notes: "Coloured box / divider / background. Style via runtime.style (background, border*, boxShadow).",
|
|
159
163
|
},
|
|
160
|
-
line: { events: "none", notes: "Separator line — style via runtime.style background/border." },
|
|
161
|
-
gallery: { specials: { media: "Array of media (image) objects." }, config: { showThumbnail: "Show thumbnails.", showNavigation: "Show nav arrows.", thumbnailPosition: "none|top|bottom|left|right." }, events: "none" },
|
|
162
|
-
carousel: { config: { slideWidth: "Slide width (px).", slideItems: "Visible slides count." }, events: "none", notes: "Holds slide children." },
|
|
163
|
-
swiper: { config: {}, events: "
|
|
164
|
+
line: { specials: { type: "horizontal | vertical." }, events: "none", notes: "Separator line — style via runtime.style background/border." },
|
|
165
|
+
gallery: { specials: { media: "Array of media (image) objects.", showNavigation: "Show nav arrows (boolean).", arrowColor: "Arrow colour.", autoplay_time: "Autoplay interval (s)." }, config: { showThumbnail: "Show thumbnails.", showNavigation: "Show nav arrows.", thumbnailPosition: "none|top|bottom|left|right.", image_ratio: "Image ratio (auto|…).", img_object_fit: "cover|contain.", showPaginate: "Pagination style (bar|none)." }, events: "none" },
|
|
166
|
+
carousel: { specials: { type: "slide_only | …", autoplay: "on|off.", autoplay_time: "Seconds per slide.", arrowColor: "Arrow colour.", slides: "Slide list [{id,name}]." }, config: { slideWidth: "Slide width (px).", slideItems: "Visible slides count.", slideWidthUnit: "px|%.", showPaginate: "Pagination style (bar-dot|…).", paginateMode: "auto|manual.", arrowWidth: "Arrow width.", navColor: "Nav colour." }, events: "none", notes: "Holds slide children." },
|
|
167
|
+
swiper: { specials: { autoplay: "on|off.", autoplayDelay: "ms between slides.", paginate: "Show pagination (boolean).", paginateBar: "bullet|bar|fraction.", direction: "row|column.", infinity: "Loop (boolean).", transitionMode: "slide|fade.", transitionTime: "ms.", auto_hide_navigation: "Hide arrows until hover (boolean).", arrowIcon: "Arrow SVG." }, config: { navColor: "Arrow colour.", navSize: "Arrow size (px).", navBackground: "Arrow background.", bulletSizeRow: "Bullet size.", barWidth: "Progress bar width.", fractionFontSize: "Fraction text size." }, events: "tab — fires on slide change.", notes: "Full-width hero/banner slider — holds slide children. The most common homepage hero." },
|
|
164
168
|
slide: { events: "none", notes: "A single slide inside a carousel/swiper." },
|
|
165
|
-
embed: { specials: { iframe: "Raw HTML / iframe markup." }, events: "none" },
|
|
166
|
-
googlemap: { specials: { iframe: "Google Maps embed iframe string." }, events: "none" },
|
|
167
|
-
countdown: { specials: { time: "Target date/time.", type: "Countdown mode." }, events: "none", notes: "
|
|
168
|
-
breadcrumb: { specials: { options: "Per-context paths (search/product/category/blog/post/default).", icon: "Separator string e.g. '>'." }, events: "none" },
|
|
169
|
+
embed: { specials: { iframe: "Raw HTML / iframe markup.", htmlCode: "Raw HTML/JS snippet (type='code').", type: "code | iframe." }, events: "none", notes: "Raw HTML/JS embed — set htmlCode (type:'code') or iframe." },
|
|
170
|
+
googlemap: { specials: { iframe: "Google Maps embed iframe string.", type: "code | place." }, config: { maxHeight: "Map max height (px)." }, events: "none" },
|
|
171
|
+
countdown: { specials: { time: "Target date/time.", type: "Countdown mode.", duration: "Countdown length (s).", repeat: "Restart when finished (boolean).", typeShow: "Largest unit shown (day|minute|…).", showDay: "Show days (boolean).", showHours: "Show hours (boolean).", showSecond: "Show seconds (boolean).", isPromotion: "Tie to a promotion (boolean).", durationStart: "Start datetime.", durationEnd: "End datetime.", dailyStart: "Daily reset start (HH:MM:SS).", dailyEnd: "Daily reset end.", positionTitle: "Title position (top|bottom).", showText: "Show the title text (boolean)." }, config: { bgTop: "Top-digit background.", bgBottom: "Bottom-digit background.", sizeDot: "Separator dot size.", spacingTitle: "Gap to title." }, events: "none", notes: "Countdown timer (flash sale / launch). Set duration or durationStart/End." },
|
|
172
|
+
breadcrumb: { specials: { options: "Per-context paths (search/product/category/blog/post/default).", icon: "Separator string e.g. '>'." }, config: { hoverColor: "Link hover colour." }, events: "none", notes: "Auto-builds the trail (Home › Category › Product) from the current page — common on category/product pages." },
|
|
169
173
|
"list-ordered": { specials: { tableItems: "Column definitions [{name,key,i18nKey}]." }, events: "none" },
|
|
170
174
|
// ── layout ──
|
|
171
175
|
section: {
|
|
172
176
|
specials: { global: "Mark as a global/shared section (reused across pages).", custom_class: "CSS class.", layout: "Nested layout payload (advanced)." },
|
|
177
|
+
config: { stickyPosition: "Make the section sticky: default | autobottom | none.", stickyTop: "Sticky offset from top (px).", showShadowWhenSticky: "Add a shadow when stuck (0/1).", video_background: "Section video background {background_display,…}.", pattern_overlay: "Overlay pattern image url.", apply_pattern_overlay: "Apply the overlay pattern (boolean).", nameLineClamp: "Clamp the section title to N lines." },
|
|
173
178
|
events: "none",
|
|
174
|
-
notes: "Top-level band; centred 3-column grid. Children go in the centre column (new_section handles this).",
|
|
179
|
+
notes: "Top-level band; centred 3-column grid. Children go in the centre column (new_section handles this). Make a header section sticky with config.stickyPosition; add a video/pattern background via config.",
|
|
175
180
|
},
|
|
176
|
-
container: { specials: { tabIndex: "Tab order.", custom_class: "CSS class.", custom_css: "Raw CSS." }, config: { maxWidth: "Max width.", maxWidthUnit: "Max-width unit.", fixedPosition: "
|
|
181
|
+
container: { specials: { tabIndex: "Tab order.", custom_class: "CSS class.", custom_css: "Raw CSS." }, config: { maxWidth: "Max width.", maxWidthUnit: "Max-width unit.", fixedPosition: "Float/pin the box (e.g. bottom_right) — for back-to-top / chat bubbles.", fixedRight: "Pinned offset from right (px).", fixedBottom: "Pinned offset from bottom (px).", fixedLeft: "Pinned offset from left (px).", stickyPosition: "Sticky mode.", stickyTop: "Sticky offset from top (px).", stickyBottom: "Sticky offset from bottom (px).", pinnedPoint: "Section id where pinning starts.", unpinnedPoint: "Section id where pinning ends.", useAutoScroll: "Auto-scroll the box (boolean).", initMaxHeight: "Collapsed max-height (px).", isUseInitMaxHeight: "Animate from initMaxHeight (boolean).", maxHeight: "Expanded max-height (px).", animation: "Entrance animation." }, events: "click, hover — clickable groups are common.", notes: "Generic grid box; nest children with their own grid. Pin a floating button/sidebar via config.fixedPosition; sticky filters via stickyTop + pinnedPoint/unpinnedPoint." },
|
|
177
182
|
row: { events: "none", notes: "Simple horizontal wrapper." },
|
|
178
183
|
tabs: { specials: { activeTab: "Default active tab index.", tabs: "Tab definitions [{id,name}].", navMode: "How tabs switch: toggle | …", showNav: "Show the tab nav (boolean).", showBullet: "Show bullets (boolean).", showDivider: "Show a divider (boolean)." }, config: { navPosition: "top|left|right|bottom.", alignNav: "Nav alignment.", nav_display_style: "Nav style." }, events: "tab — fires when the active tab changes.", notes: "Tabbed container; each tab maps to a tab item the content reacts to (e.g. account panels, product detail/description/reviews)." },
|
|
179
184
|
collapse: { events: "none", notes: "Accordion container (collapse-item children)." },
|
|
@@ -239,24 +244,24 @@ export const ELEMENT_ATTRS = {
|
|
|
239
244
|
switch: { specials: { defaultValue: "Default on/off (boolean)." }, config: { backgroundSlider: "Track colour.", colorRound: "Knob colour.", colorSlider: "Active track colour." }, events: "none", notes: "Toggle; style width/height." },
|
|
240
245
|
// ── commerce ──
|
|
241
246
|
"grid-product": {
|
|
242
|
-
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)." },
|
|
243
|
-
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." },
|
|
247
|
+
specials: { displayStyle: "default | only_image | border.", original_price_position: "left | right | top | bottom.", 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).", rating_number_type: "Rating count style (review_count|…).", 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).", max_show_categories: "Max category labels per card.", show_total_sold: "Show units sold (boolean).", show_wholesale_price: "Show wholesale price (boolean).", show_divider: "Show a divider in the card (boolean).", show_button: "Show an add-to-cart/quick button (boolean).", show_button_on_hover: "Reveal the button only on hover (boolean).", textQuickBtn: "Quick add-to-cart button label.", action_add_to_cart: "Add-to-cart behaviour (numeric mode).", action_attachment_add_to_cart: "After add-to-cart: open_cart | …", scroll_type: "Pagination scroll behaviour (scroll_to_top|…).", type_view_more: "Load-more style.", barValue: "Stock bar source (remain_quantity|…).", saleInfoDisplayText: "In-stock label.", saleInfoSoldoutText: "Sold-out label.", disable_filter: "Ignore active filters (boolean).", disable_search: "Ignore the search query (boolean).", show_detail_price: "Show a detailed price breakdown (boolean).", show_quantity: "Show a quantity stepper on the card (boolean).", show_wholesale_quantity: "Show wholesale tiers (boolean).", auto_hide_without_star: "Hide rating when none (boolean).", promotion_id: "Restrict to a promotion's products.", action_product_card: "Click behaviour for the whole card (numeric mode).", store_show_attribute_template_1: "Attribute-template plugin config {show_cart,…}.", filledStarIcon: "Filled-star SVG.", unfilledStarIcon: "Empty-star SVG.", 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)." },
|
|
248
|
+
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.", image_border_radius: "Card image corner radius (px).", image_placement: "Image vs text layout (column|row).", 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).", price_padding_x: "Horizontal 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).", productNameFontWeight: "Product-name weight.", productNameColor: "Product-name colour.", productNameHover: "Product-name hover colour.", productNamePaddingY: "Vertical padding of the name (px).", productCategoryFontSize: "Category-label size (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).", cardBackground: "Card background colour.", ribbonBackground: "Ribbon background.", ribbonFont: "Ribbon font.", ribbonPadding: "Ribbon padding.", ribbonGap: "Ribbon gap.", customRibbonStyle: "Per-ribbon style overrides {ribbonId:{…}}.", paginationColor: "Pagination dot colour.", activePaginationColor: "Active pagination colour.", sizeThumbnail: "{ width, height } of the card image." },
|
|
244
249
|
events: "none",
|
|
245
250
|
bindings: ["product::product_image", "product::product_name", "product::product_price"],
|
|
246
251
|
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.",
|
|
247
252
|
},
|
|
248
|
-
"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"] },
|
|
249
|
-
"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)
|
|
253
|
+
"slider-product": { specials: { displayStyle: "default|only_image|border.", original_price_position: "left|right|top.", category_id: "Source category id.", products_per_load: "Products to fetch.", autoplay: "on|off.", autoplay_time: "ms per slide.", autoplay_step: "Slides advanced per step.", on_hover: "zoom|swap.", show_navigation: "Show arrows (boolean).", show_nav_on_hover: "Reveal arrows on hover (boolean).", arrow_icon: "Arrow SVG.", show_rating: "Show rating (boolean).", show_ribbon: "Show ribbon (boolean).", show_product_name: "Show name (boolean).", show_product_price: "Show price (boolean).", show_button: "Show add-to-cart button (boolean).", action_add_to_cart: "Add-to-cart mode.", typeLinkCategory: "Related source (similar_product|…).", randomDisplay: "Randomise order (boolean)." }, config: { slideItems: "Visible products.", item_show: "Visible products (real 1–6, fractional ok e.g. 3.6).", slideWidth: "Card width.", image_ratio: "Aspect ratio (industry-dependent, see grid-product).", productNameFontSize: "Name size.", productPriceFontWeight: "Price weight (bold).", productPriceColor: "Price colour.", image_border_radius: "Card image radius.", sizeThumbnail: "{width,height} of card image." }, events: "none", bindings: ["product::product_image", "product::product_name", "product::product_price"], notes: "Horizontal product carousel (homepage 'featured/related'). Same card config family as grid-product + slider keys (item_show, autoplay, arrows)." },
|
|
254
|
+
"product-gallery": { specials: { showNavigation: "Show the thumbnail strip / nav (boolean — real templates often false).", show_ribbon: "Show a ribbon on the image (boolean).", zoom_type: "Hover zoom: none | lens | …", on_hover: "Hover effect on the main image (e.g. zoom).", arrowColor: "Nav arrow colour.", autoplay: "Auto-advance images (on|off).", autoplay_video: "Auto-play a product video (boolean).", type_split_video: "How a video splits from images (none|…).", infinity: "Loop images (boolean).", auto_resize_height: "Fit height to image (boolean)." }, config: { sizeThumbnail: "{ width, height } of the main image (real 500–1044).", image_ratio: "Main image ratio (often 'auto').", img_object_fit: "cover|contain.", showThumbnail: "Show the thumbnail strip (boolean).", thumbnailPosition: "left|bottom|…", thumbnailWidth: "Thumb width (px).", thumbnailHeight: "Thumb height (px).", scrollDirection: "Thumb scroll axis (horizontal|vertical).", arrowWidth: "Arrow width.", arrowHeight: "Arrow height.", max_show_items: "Max thumbnails shown." }, events: "none", notes: "Product detail image gallery (product page): main image + thumbnail strip (thumbnailPosition) + optional hover zoom (zoom_type)." },
|
|
250
255
|
"product-image-carousel": { events: "none", notes: "Product image carousel (product page)." },
|
|
251
256
|
"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]." },
|
|
252
|
-
"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." },
|
|
253
|
-
"quantity-input": { specials: { spinner: "Native spinner style: hide-spin (product/cart, the default) | circle (checkout).", showRightBtn: "Show the
|
|
254
|
-
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." },
|
|
255
|
-
payment: { events: "none", notes: "Payment methods block (checkout)." },
|
|
257
|
+
"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.", itemCountFont: "Badge font (theme var).", itemCountFontSize: "Badge font size (e.g. 11px).", itemCountFontWeight: "Badge font weight.", itemCountColor: "Badge text colour.", itemBackgroundColor: "Badge background 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." },
|
|
258
|
+
"quantity-input": { specials: { spinner: "Native spinner style: hide-spin (product/cart, the default) | circle (checkout).", showLeftBtn: "Show the minus button (boolean).", showRightBtn: "Show the plus button (boolean).", min: "Minimum quantity.", max: "Maximum quantity." }, config: { textColor: "Quantity text colour.", btnIncrease: "Plus-button style {borderColor,background,…}.", btnDecrease: "Minus-button style." }, events: "none", notes: "Quantity stepper (product/cart). Defaults to spinner:'hide-spin'." },
|
|
259
|
+
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).", tooltip: "Show a tooltip on hover (boolean)." }, config: { borderColorHover: "Swatch hover border colour.", type: "Display: hover | regular.", selectedType: "Selected style (outer|…).", sizeImage: "Image swatch size (px).", tooltipBackground: "Tooltip background.", tooltipColor: "Tooltip text colour.", tooltipPosition: "top|bottom|…" }, 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." },
|
|
260
|
+
payment: { specials: { options: "Payment methods [{type,name,image,active}].", icon_color: "Method icon colour.", runNow: "Auto-run the selected method (boolean)." }, config: { activeColor: "Selected-method colour." }, events: "none", notes: "Payment methods block (checkout)." },
|
|
256
261
|
"delivery-method": { specials: { options: "[{type: delivery|store_pickup, name, active}]." }, events: "none" },
|
|
257
262
|
"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]." },
|
|
258
|
-
"order-history": { events: "none", notes: "Member order history (member page)." },
|
|
259
|
-
coupon: { events: "none", notes: "Coupon / discount
|
|
263
|
+
"order-history": { specials: { items_per_load: "Orders per page.", type_view_more: "Load-more style.", editView: "Layout mode (data|…).", default_filter: "Default status filter ids.", countdown_time: "Auto-cancel countdown (hours).", cancel_text: "Cancel-order label.", order_id_text: "Order-code label.", payment_text: "Payment label.", total_price_text: "Total label.", item_attr_text: "Variation label.", is_scroll_to_top: "Scroll up on page change (boolean)." }, config: { show_variation: "Show item variations (boolean).", productNameClamp: "Clamp product name lines.", imageSize: "Thumbnail size (px).", priceColor: "Price colour." }, events: "none", notes: "Member order history (member page)." },
|
|
264
|
+
coupon: { specials: { field_name: "coupon.", label: FIELD.label, placeholder: FIELD.placeholder, show_label: FIELD.show_label, required: FIELD.required, title: "Heading text.", auto_fill_coupon: "Pre-fill an available coupon (boolean)." }, config: { ...FIELD_CONFIG }, events: "none", notes: "Coupon / discount-code input (cart/checkout). Place inside a form_discount." },
|
|
260
265
|
"product-overlay": { specials: { type: "discount | custom." }, events: "none", notes: "Badge overlaid on a product card." },
|
|
261
266
|
"product-review": {
|
|
262
267
|
specials: {
|
|
@@ -278,13 +283,13 @@ export const ELEMENT_ATTRS = {
|
|
|
278
283
|
},
|
|
279
284
|
"masonry-review": { specials: { view_product_mode: "How linked products display in the review wall." }, events: "none", notes: "Masonry wall of reviews." },
|
|
280
285
|
"flash-sale": { specials: { promotion_advance_id: "Promotion id (or 'none')." }, events: "none" },
|
|
281
|
-
promotions: { events: "none", bindings: ["promotion_item::image", "promotion_item::name", "promotion_item::code", "promotion_item::description", "promotion_item::end_date"] },
|
|
282
|
-
"promotions-short": { events: "none", bindings: ["promotion_item::name", "promotion_item::code"] },
|
|
283
|
-
"grid-category": { config: { columns: "Categories per row." }, events: "none", notes: "Lists product categories. Create categories first (create_product_category)." },
|
|
284
|
-
"slider-category": { config: { columns: "Visible categories." }, events: "none" },
|
|
286
|
+
promotions: { specials: { displayPromotions: "Which promotion kinds to list (e.g. ['coupon_id_multiple_times','discount_by_coupon'])." }, config: { direction: "horizontal | vertical.", promotionBorderColor: "Card border colour.", promotionDotColor: "Perforation dot colour." }, events: "none", bindings: ["promotion_item::image", "promotion_item::name", "promotion_item::code", "promotion_item::description", "promotion_item::end_date"], notes: "Lists active promotions/coupons (often with a copy-code button)." },
|
|
287
|
+
"promotions-short": { specials: { displayPromotions: "Promotion kinds to list." }, config: { direction: "horizontal | vertical.", promotionBorderColor: "Border colour.", promotionDotColor: "Dot colour." }, events: "none", bindings: ["promotion_item::name", "promotion_item::code"] },
|
|
288
|
+
"grid-category": { specials: { showCategories: "Categories to show [{id,...}] (else all).", isAutoCatchMenuLevelFirst: "Auto-pick top-level categories (boolean)." }, config: { columns: "Categories per row.", minimum_card_width: "Min card width (autofit, px).", sizeThumbnail: "{width,height} of the category image.", responsive: "fixed | autofit.", imageBorderRadius: "Image radius (px).", cardBackground: "Card background.", cardBorderRadius: "Card radius.", name_padding_y: "Padding around the name." }, events: "none", notes: "Lists product categories. Create categories first (create_product_category)." },
|
|
289
|
+
"slider-category": { specials: { showCategories: "Categories to show [{id,...}].", on_hover: "Card hover effect (zoom-in|…)." }, config: { columns: "Visible categories.", minimum_card_width: "Min card width (px).", sizeThumbnail: "{width,height} of the image.", imageBorderRadius: "Image radius.", navSize: "Arrow size (px).", arrowColor: "Arrow colour." }, events: "none" },
|
|
285
290
|
"customer-address": { events: "none", bindings: ["customer_address::full_name", "customer_address::address", "customer_address::phone_number", "customer_address::pdc", "customer_address::is_default"], notes: "Member saved addresses." },
|
|
286
|
-
wishlist: { specials: { svg: "Icon SVG.", itemCount: "Badge count." }, events: "click." },
|
|
287
|
-
"favorite-icon": { events: "click — toggle favourite." },
|
|
291
|
+
wishlist: { specials: { svg: "Icon SVG.", itemCount: "Badge count." }, config: { itemCountColor: "Badge text colour.", itemBackgroundColor: "Badge background.", itemCountFontSize: "Badge size.", itemCountFontWeight: "Badge weight.", itemCountBorderRadius: "Badge radius.", itemCountFontFamily: "Badge font." }, events: "click — opens the wishlist." },
|
|
292
|
+
"favorite-icon": { config: { mask: "Heart icon SVG mask.", colorActive: "Colour when favourited." }, events: "click — toggle favourite (add_wishlist_product / wishlist_remove_item).", notes: "Heart toggle on a product card; pairs with the wishlist element in the header." },
|
|
288
293
|
"bonus-items": { specials: { typeBonus: "combo_product | other." }, events: "none" },
|
|
289
294
|
// ── navigation ──
|
|
290
295
|
menu: { specials: { type: "horizontal | vertical | hamburger | collapse | grid | anchor.", sync: "Auto-sync items with site pages (boolean).", fullField: "Stretch items to fill the menu width (boolean).", shapeType: "'Icon' to render a hamburger/icon trigger instead of text.", url: "Icon image url (icon-style menu).", isPostList: "Build items from blog posts (boolean).", tabIndex: "Bind to a tab item." }, config: { showArrow: "Show the dropdown caret on items with a submenu (boolean).", textColor: "Item text colour (often a theme var like var(--color_20)).", colorHover: "Item hover colour.", activeColor: "Active item colour.", "--padX": "Horizontal padding inside each item (CSS var, e.g. 15px).", mask: "Icon SVG mask (icon-style menu).", arrowColor: "Caret colour.", arrowSize: "Caret size (px).", backgroundHover: "Item hover background.", borderColorHover: "Item hover border colour.", borderRadiusHover: "Item hover radius.", fontWeightHover: "Item hover font weight.", activeLink: "Active-item style object (e.g. {fontWeight:'bold'}).", maxHeight: "Max dropdown height (px)." }, events: "none", notes: "Holds menu-item children. Real headers carry TWO menus (a horizontal desktop menu + a hamburger/collapse mobile menu). Colour items via theme vars (var(--color_20))." },
|
|
@@ -298,14 +303,14 @@ export const ELEMENT_ATTRS = {
|
|
|
298
303
|
"dropdown-content": { events: "none", notes: "The panel a dropdown toggles." },
|
|
299
304
|
"language-menu": { specials: { show_flag: "Show country flags (boolean).", type: "dropdown | inline." }, config: { display: "full | abbreviated.", flagSize: "Flag size (px).", color: "Text colour.", colorHover: "Hover colour.", backgroundDropdown: "Dropdown background.", colorSelected: "Selected language colour.", dropdown_icon_size: "Caret size (px)." }, events: "none", notes: "Language switcher (multilingual sites)." },
|
|
300
305
|
// ── blog ──
|
|
301
|
-
"post-list": { events: "none", notes: "Lists blog articles. Create blog category + articles first." },
|
|
302
|
-
"slider-post": { config: { slideItems: "Visible posts.", slideWidth: "Card width." }, events: "none" },
|
|
306
|
+
"post-list": { specials: { numbers_posts_to_show: "Total posts to show.", numbers_posts_to_show_per_page: "Posts per page.", posts_display_by: "Source mode (category/recent/…).", category_id: "Blog category id (or 'similar_posts').", readButtonText: "Read-more label.", on_hover: "Card hover effect (zoom).", tagTitle: "Title HTML tag (h3…).", tagDescription: "Description tag.", tagDatePublished: "Date tag.", tagCategory: "Category tag." }, config: { posts_per_row: "Posts per row.", image_ratio: "Card image ratio (3/2|1/1|…).", image_align: "Image position (top|left).", imageBorderRadius: "Image radius (px).", responsive: "fixed | custom.", spacing_between_posts: "Gap between cards (px).", showCategory: "Show category (0/1).", showPublishDate: "Show date (0/1).", showDescription: "Show excerpt (0/1).", showReadButton: "Show read-more (0/1).", descriptionFontSize: "Excerpt size.", descriptionColor: "Excerpt colour.", dateColor: "Date colour." }, events: "none", notes: "Lists blog articles (children are post-overlay cards). Create blog category + articles first." },
|
|
307
|
+
"slider-post": { specials: { numbers_posts_to_show: "Posts to show.", category_id: "Blog category id (or 'all_posts').", readButtonText: "Read-more label.", on_hover: "Hover effect (zoom)." }, config: { slideItems: "Visible posts.", slideWidth: "Card width.", posts_per_row: "Posts per view.", image_ratio: "Card image ratio.", responsive: "fixed | custom.", spacing_between_posts: "Gap (px).", layout: "Card layout variant." }, events: "none" },
|
|
303
308
|
"grid-blog": { specials: { showBlogs: "Categories to show [{...}]." }, config: { columns: "Posts per row." }, events: "none" },
|
|
304
309
|
"slider-blog": { specials: { showBlogs: "Categories to show." }, config: { columns: "Visible posts." }, events: "none" },
|
|
305
310
|
"post-overlay": { specials: { type: "regular | custom." }, events: "none", notes: "Post card overlay (post page)." },
|
|
306
311
|
"blog-overlay": { specials: { type: "regular | custom." }, events: "none" },
|
|
307
312
|
// ── filters / widgets / states (mined from 34 templates) ──
|
|
308
|
-
tags: { specials: { ...FILTER_SPECIALS, activeMode: "How active tags render.", selectionMode: "single | multiple.",
|
|
313
|
+
tags: { specials: { ...FILTER_SPECIALS, activeMode: "How active tags render.", selectionMode: "single | multiple.", auto_category_type: "Auto-source: product_category | …", auto_option: "Behaviour on click: filter | redirect.", max_child_categories: "Max child categories listed.", use_filter_or: "OR vs AND across selected tags (boolean).", keyword_suggestions: "Suggested search keywords [{key,value}]." }, config: { tags_layout: "Tag layout style." }, events: "click — filters the linked grid-product (or redirects).", notes: "Tag/attribute/keyword chips that FILTER a product grid (category page) — set filter_elements + sync_tab:'tag'; or auto_option:'redirect' to navigate." },
|
|
309
314
|
"auto-number": { specials: { startNumber: "Start value.", endNumber: "End value.", jumpNumber: "Increment step.", duration: "Count-up duration (s)." }, config: { strokeColor: "Text stroke.", textColor: "Number colour." }, events: "none", notes: "Animated count-up stat (e.g. '10,000+ customers')." },
|
|
310
315
|
agency: { specials: { datagrid_id: "Linked data grid id.", googleTarget: "Google-map target." }, config: { hoverColor: "Hover colour.", activeColor: "Active colour." }, events: "none", bindings: ["agency::name", "agency::phone_number", "agency::address", "agency::time"], notes: "Store-locator / branch list (repeater over agency::*)." },
|
|
311
316
|
"user-point-log": { specials: { itemGap: "Row gap.", noteColor: "Note colour.", datetimeColor: "Date colour." }, events: "none", notes: "Loyalty reward-point history (member page)." },
|
|
@@ -316,6 +321,23 @@ export const ELEMENT_ATTRS = {
|
|
|
316
321
|
"lesson-items": { events: "none", notes: "Lessons list inside a module (course app)." },
|
|
317
322
|
"next-lesson-droppable": { events: "none", notes: "Next-lesson panel (course app)." },
|
|
318
323
|
"list-lesson-droppable": { events: "none", notes: "Lessons droppable list (course app)." },
|
|
324
|
+
// ── marketing / popups / misc widgets (rarely in page sources; built via apps/global_sources) ──
|
|
325
|
+
popup: { specials: { effect: "Open animation (fade-in|slide|…).", timeAnim: "Animation duration (s).", trigger: "When it opens: load | delay | exit_intent | scroll.", delay: "Seconds before auto-open (trigger=delay).", onlyOnce: "Show once per visitor (boolean).", overlay: "Dim the page behind (boolean)." }, config: { popupHorizontalPosition: "left | center | right.", popupVerticalPosition: "top | center | bottom." }, events: "hide — fires when the popup closes.", notes: "Modal/overlay. NOT a page section — wrap a section in a popup node and save it as a global_source (component:'popup'). Open/close from any element via events open_popup/close_popup {popup_id}. See get_build_guide → Popups." },
|
|
326
|
+
notify: { specials: { type: "Toast/banner kind.", autoClose: "Auto-dismiss (boolean).", duration: "Visible time (s)." }, events: "none", notes: "Notification / toast banner (e.g. add-to-cart confirmation). Often referenced by add_to_cart's activeNotify." },
|
|
327
|
+
"random-number": { specials: { min: "Lowest value.", max: "Highest value." }, events: "none", notes: "Displays a random number (minigame / fake-stock urgency widget)." },
|
|
328
|
+
table: { specials: { datagrid_id: "Linked data-grid id (the table's data source).", tableItems: "Column definitions [{name,key}]." }, config: { titleBackground: "Header background.", titleColor: "Header text colour.", oddBackground: "Odd-row background.", evenBackground: "Even-row background." }, events: "none", notes: "Data table bound to a data grid (specs / comparison)." },
|
|
329
|
+
"rectangle-dataset": { events: "none", bindings: ["product::product_image", "category::category_image"], notes: "A box/background bound to a dataset field (like image-dataset but a styled rectangle) — set bindings[].target." },
|
|
330
|
+
"reward-point": { specials: { ...FIELD }, config: { ...FIELD_CONFIG }, events: "none", notes: "Field to redeem loyalty reward points at checkout (member). field_name 'reward_point'." },
|
|
331
|
+
"referral-code": { specials: { field_name: "referral / referral_code.", label: FIELD.label, placeholder: FIELD.placeholder, show_label: FIELD.show_label }, config: { ...FIELD_CONFIG }, events: "none", notes: "Shows/enters a member referral code (affiliate/loyalty)." },
|
|
332
|
+
"lucky-wheel": { specials: { segments: "Wheel prizes [{label,…}].", spin_limit: "Spins allowed per user." }, events: "click — spins the wheel.", notes: "Spin-to-win minigame (marketing app)." },
|
|
333
|
+
"tee-form": { specials: { product_id: "Designable product id." }, events: "none", notes: "Print-on-demand / product-design form (apparel app)." },
|
|
334
|
+
warehouse: { specials: { warehouses: "Store/branch list [{id,name,address,…}]." }, config: { activeColor: "Selected branch colour.", hoverColor: "Hover colour.", distanceWarehouse: "Gap between branches (px)." }, events: "click — picks a pickup branch.", notes: "Store/warehouse pickup selector (checkout)." },
|
|
335
|
+
"warehouse-dataset": { events: "none", bindings: ["warehouse::name", "warehouse::address"], notes: "Warehouse/branch field bound to a dataset." },
|
|
336
|
+
calendar: { specials: { mode: "Booking view (month|week|day).", min_date: "Earliest selectable date.", max_date: "Latest selectable date." }, events: "none", notes: "Booking calendar (appointment app). Holds calendar-content." },
|
|
337
|
+
"calendar-content": { events: "none", notes: "A day/slot cell inside a calendar (appointment app)." },
|
|
338
|
+
"collapse-content": { events: "none", notes: "The expandable content panel inside a collapse-item (accordion body)." },
|
|
339
|
+
"question-container": { specials: { question_type: "single | multiple | text.", required: "Answer required (boolean)." }, events: "none", notes: "One question wrapper in a quiz/survey form (question_form)." },
|
|
340
|
+
"input-product-note": { specials: { ...FIELD }, config: { ...FIELD_CONFIG }, events: "none", notes: "Per-product note field (passes a note with the product into the cart). field_name 'product_note'." },
|
|
319
341
|
};
|
|
320
342
|
const describe = (type, key, where) => {
|
|
321
343
|
const curated = ELEMENT_ATTRS[type] || {};
|
package/dist/changelog.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"v": "1.25.0",
|
|
4
|
+
"d": "26/06/2026",
|
|
5
|
+
"type": "Changed",
|
|
6
|
+
"en": "list_elements now documents 16 previously-uncovered element types, completing curated attribute coverage across all 132 factory types: popup…",
|
|
7
|
+
"vi": "list_elements nay tài liệu hóa 16 kiểu phần tử trước đây chưa được ghi lại, hoàn thiện độ phủ thuộc tính curated cho toàn bộ 132 kiểu factory: popup…"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"v": "1.24.0",
|
|
11
|
+
"d": "26/06/2026",
|
|
12
|
+
"type": "Changed",
|
|
13
|
+
"en": "list_elements now documents tabIndex and text_animation_type as shared specials present on every element, covering tab-panel visibility binding and…",
|
|
14
|
+
"vi": "list_elements nay tài liệu hóa tabIndex và text_animation_type là các specials dùng chung có trên mọi phần tử, bao gồm gắn kết hiển thị/ẩn cho…"
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"v": "1.23.0",
|
|
4
18
|
"d": "25/06/2026",
|
|
@@ -26,19 +40,5 @@
|
|
|
26
40
|
"type": "Changed",
|
|
27
41
|
"en": "The header generated by scaffold_global_sections now uses a menu element with menu-item children for navigation links, matching real production…",
|
|
28
42
|
"vi": "Header được tạo bởi scaffold_global_sections nay sử dụng phần tử menu với các phần tử con menu-item cho các liên kết điều hướng, khớp với cấu trúc…"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"v": "1.19.1",
|
|
32
|
-
"d": "25/06/2026",
|
|
33
|
-
"type": "Fixed",
|
|
34
|
-
"en": "create_site_from_template now auto-generates a URL-safe slug from the site name when none is supplied, fixing the 400 error returned by the backend…",
|
|
35
|
-
"vi": "create_site_from_template nay tự động tạo slug an toàn cho URL từ tên site khi không có slug nào được cung cấp, khắc phục lỗi 400 mà backend trả về…"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
"v": "1.19.0",
|
|
39
|
-
"d": "25/06/2026",
|
|
40
|
-
"type": "Added",
|
|
41
|
-
"en": "New scaffold_global_sections tool generates a fully-designed global Header and Footer in one call — logo, nav links, cart icon, CTA button, and a…",
|
|
42
|
-
"vi": "Tool mới scaffold_global_sections tạo Header và Footer toàn cục đã thiết kế sẵn trong một lần gọi — logo, liên kết điều hướng, icon giỏ hàng, nút…"
|
|
43
43
|
}
|
|
44
44
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webcake-storefront-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.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",
|