@vectoriox/iox-builder 11.17.0 → 11.18.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.
|
@@ -19,14 +19,15 @@ import { DialogModule } from 'primeng/dialog';
|
|
|
19
19
|
import * as i2$1 from '@vectoriox/iox-ui';
|
|
20
20
|
import { nodeCssId, needsGroupName, resolveBoundValue, STRUCTURAL_STATES as STRUCTURAL_STATES$1, VALIDATION_STATES as VALIDATION_STATES$1, VALIDATION_STATE_CLASS as VALIDATION_STATE_CLASS$1, DEFAULT_WIDTH_BY_TYPE, TEXT_DIRECTION_KEY, TEXT_ALIGN_KEY, TextAlign, COLOR_SCHEME_TRAIT, COLOR_SCHEMES, ColorScheme, LinkType, MAX_LINES_KEY, A11yTrait, BREAKPOINTS, Breakpoint, withSchemeInk, stripSuppressedProps, DeclarationContext, planPartRule, gateHoverRule, planResponsiveRules, resolveStyleProps, planStateRule, splitOuterProps, OUTER_STYLE_PROPS, compileTokenCssBlocks, catalogFontId, fontsForTokens, GOOGLE_FONTS_FILE_ORIGIN, googleFontHref, compileDeclarations, isLastEmittedStateKey, wrapInBreakpointQuery, BreakpointQueryKind, NEW_NODE_STYLE_DEFAULTS, defaultElementStyleFor, applyElementStyle, planDataSource, dataSourcePlanToRequest, normalizeCollectionResult, resolveRepeaterItems, getByPath, computeRelative, PROGRESS_ATTRIBUTE, interactionMarkerAttributes, cascadeChain, attachScrollProgress, ContextStore, ENTRANCE_ACTION_TYPES, EXIT_ACTION_TYPES, ComponentInstanceRegistryService, syncInteractionMarkers, entranceStartsHidden, isActionEnabled, restoreCountUp, SCROLL_PROGRESS_TRIGGER, armInteractionCounts, splitPressFeedback, isHoverPointer, isContextAction, contextActionEffect, resolveContextValue, effectiveActionType, INTERACTION_HIDDEN_ATTRIBUTE, COUNT_UP_ACTION, motionAllowed, settleInteraction, settleModeFor, playInteraction, resolveInteractionEasing, entranceDelay, repeatedRowIndex, entrancePreStateStyle, buildInteractionKeyframes, showToast, declaredInputNames, emptyImagePlaceholder, syncNodeDesignClasses, nodeTraitValue, syncNodeA11yAttributes, nodeA11yAttributes, safeSetInput, colorSchemeOf, withStateTransitions, composeVirtualTraits, stateNamesIn, partClassName, switchElementStyle, releaseElementStyle, countOverrides, setOverride, breakpointDef, breakpointForWidth, FormRenderState, needsAccessibleName, resolveInputs, setInputOverride, barReserveClass, collectContextSlotKeys, withContextSlots, compilePageStyle, nodeUsesContext, attachTooltips, showToastDesign, TOOLTIP_ATTRIBUTE, hidingHeadersIn, HeaderRuntime, isScrolled, SCROLLED_ATTRIBUTE, syncSubmitButtons, IS_PREVIEW, buttonBlockHref, layerFrame, rectInLayer, placeFloating, FloatingAlign, popoverSide, bootSlider, IoxPageModule, PALETTE_PRESETS, elementStyleById, PART_CLASS_NAMES } from '@vectoriox/iox-ui';
|
|
21
21
|
export { ComponentInstanceRegistryService, VIRTUAL_TRAIT_KEYS, composeVirtualTraits } from '@vectoriox/iox-ui';
|
|
22
|
-
import { StructureEdit, isAccordionPart, isDisclosurePart, isSliderPart, isTabsPart, isSegmentedPart, structureRefusal, StructureRefusal, SegmentedRole, SEGMENTED_MAX_OPTIONS, AccordionRole, SEGMENTED_MIN_OPTIONS, isExclusiveItemPart, TabsRole, ITEM_OPEN_STATE, readStyle, isSegmentedRoot, segmentedDefaultOn, segmentedOptions, isTabsRoot, isTabsFromContent, tabsTriggers, isAccordionRoot, isAccordionFromContent, accordionItems, initialAccordionOpen, accordionBehaviour, exclusiveItemLabel, exclusiveRootOf, tabTriggerOf, tabLabel, removeTabPair, tabPanelOf, tabsListOf, tabsPanelsOf, nextTabKey, CompositeBehaviourTrait, ACCORDION_DEFAULT_ONS, TabsBehaviourTrait, TABS_ACTIVATE_ONS, TABS_ORIENTATIONS, MarqueeTrait, MarqueeSpeed, MarqueeDirection, DisclosureRole, isExclusiveTrigger, onCompositeItemState, isCompositeItemOn, runCompositeItemAction, shouldScrollToItem, rowIndexOf as rowIndexOf$1, slideIndexForRow, isMarqueeRoot, compositeScopeId, compositeRowKeys, isExclusiveRoot, ExclusiveRuntime, exclusiveDefaultOf, exclusiveLabelOf, exclusiveBehaviourOf, exclusiveKindOf, compositeKindOfRole, AccordionRuntime, isToggleKind, MarqueeRuntime, closestAccordionItem, isAnyCompositeRoot, SceneRole, isExclusiveList, buildCardRecipe, buildBadge, buildChip, buildAccordionRecipe, buildDisclosureRecipe, buildTabsRecipe, buildSegmentedRecipe, buildLightboxRecipe, buildMarqueeRecipe, buildCounterRecipe, buildReadingBarRecipe, NO_ELEMENT_STYLE, CompositeKind, SliderRole, accordionItemLabel, segmentedOptionLabel, isExclusivePanels, isLockedPart, accordionRootOf, accordionItemOf, addAccordionItem, addTabPair, segmentedAddRefusal, addSegmentedOption, isCompositeItem, accordionHeadingLevel, isCompositePanel, isCompositeTrigger, splitSliderChildren, hasSliderParts, SLIDE_CAPTION_TRAIT, SLIDER_SCROLL_PLAYS_TRAIT, SLIDER_PLACEMENT_TRAIT, SliderPlacement, SliderFlag } from '@vectoriox/iox-ui/composite-core';
|
|
22
|
+
import { StructureEdit, isAccordionPart, isDisclosurePart, isSliderPart, isTabsPart, isSegmentedPart, structureRefusal, StructureRefusal, SegmentedRole, SEGMENTED_MAX_OPTIONS, AccordionRole, SEGMENTED_MIN_OPTIONS, isExclusiveItemPart, TabsRole, ITEM_OPEN_STATE, readStyle, isSegmentedRoot, segmentedDefaultOn, segmentedOptions, isTabsRoot, isTabsFromContent, tabsTriggers, isAccordionRoot, isAccordionFromContent, accordionItems, initialAccordionOpen, accordionBehaviour, exclusiveItemLabel, exclusiveRootOf, tabTriggerOf, tabLabel, removeTabPair, tabPanelOf, tabsListOf, tabsPanelsOf, nextTabKey, CompositeBehaviourTrait, ACCORDION_DEFAULT_ONS, TabsBehaviourTrait, TABS_ACTIVATE_ONS, TABS_ORIENTATIONS, MarqueeTrait, MarqueeSpeed, MarqueeDirection, DisclosureRole, isExclusiveTrigger, onCompositeItemState, isCompositeItemOn, ShopActionType, runShopAction, runCompositeItemAction, shouldScrollToItem, rowIndexOf as rowIndexOf$1, slideIndexForRow, isMarqueeRoot, compositeScopeId, compositeRowKeys, isExclusiveRoot, ExclusiveRuntime, exclusiveDefaultOf, exclusiveLabelOf, exclusiveBehaviourOf, exclusiveKindOf, compositeKindOfRole, AccordionRuntime, isToggleKind, MarqueeRuntime, closestAccordionItem, isAnyCompositeRoot, SceneRole, isExclusiveList, buildCardRecipe, buildBadge, buildChip, buildAccordionRecipe, buildDisclosureRecipe, buildTabsRecipe, buildSegmentedRecipe, buildLightboxRecipe, buildMarqueeRecipe, buildCounterRecipe, buildReadingBarRecipe, SHOP_RECIPES, ShopRecipe, NO_ELEMENT_STYLE, CompositeKind, SliderRole, accordionItemLabel, segmentedOptionLabel, isExclusivePanels, isLockedPart, attachShop, ShopRole, accordionRootOf, accordionItemOf, addAccordionItem, addTabPair, segmentedAddRefusal, addSegmentedOption, isCompositeItem, accordionHeadingLevel, isCompositePanel, isCompositeTrigger, splitSliderChildren, hasSliderParts, SLIDE_CAPTION_TRAIT, SLIDER_SCROLL_PLAYS_TRAIT, SLIDER_PLACEMENT_TRAIT, SliderPlacement, SliderFlag } from '@vectoriox/iox-ui/composite-core';
|
|
23
23
|
import { formContentInHost, isInteractiveHost, findFormContentInHosts, FORM_CHANNEL_ROLE, channelHref, channelOpensNewTab, FORM_ACTIONS_ROLE, SUBMIT_BUTTON_NODE_TYPE, FORM_AFTER_SEND_TRAIT, FormAfterSend } from '@vectoriox/iox-ui/forms-core';
|
|
24
24
|
import { Subject, BehaviorSubject, of, forkJoin } from 'rxjs';
|
|
25
25
|
import interact from 'interactjs';
|
|
26
26
|
import { HeaderTrait, HeaderBehaviour, HeaderEdge, pageOpeningScheme } from '@vectoriox/iox-ui/design-core';
|
|
27
27
|
import { map, catchError } from 'rxjs/operators';
|
|
28
28
|
import * as i1 from '@angular/common/http';
|
|
29
|
-
import {
|
|
29
|
+
import { SAMPLE_PRODUCT, productInScope, simulatedCartTransport, storefrontCatalog, SAMPLE_STUDIO, SAMPLE_CART_LINE, SAMPLE_SWATCHES } from '@vectoriox/iox-ui/commerce-core';
|
|
30
|
+
import { POPOVER_ACTION_TYPE_SET, TOAST_ACTION_TYPES, itemActionOf, BEHAVIOUR_ACTION_TYPES, SHOP_ACTION_TYPES, SERVER_ELEMENT_ACTION_TYPES, CONSENT_ACTION_TYPES, opensAtClickedItem, openedDialogId, DIALOG_CLOSING_ATTRIBUTE, cancelExit, runExitMotion, popoverOpenersSelector, popoverDomId } from '@vectoriox/iox-ui/actions-core';
|
|
30
31
|
import { NavRole, navShapeBreakpoint, entranceInteraction, entranceAction, sectionEntrances, EntrancePart } from '@vectoriox/iox-ui/generation-core';
|
|
31
32
|
import { ScrollDriver, syncSceneAttributes, buildSceneRecipe } from '@vectoriox/iox-ui/scene-core';
|
|
32
33
|
import Lenis from 'lenis';
|
|
@@ -5071,6 +5072,12 @@ class InteractionEngineService {
|
|
|
5071
5072
|
this.executeBehaviourAction(node, action, selfEl);
|
|
5072
5073
|
continue;
|
|
5073
5074
|
}
|
|
5075
|
+
// Shop actions (commerce E1c). Add to cart SIMULATES: the canvas's shop runtime adds to an in-memory sample bag
|
|
5076
|
+
// (never a cart) and opens the drawer; Buy now is inert. The toast says what the live site does.
|
|
5077
|
+
if (SHOP_ACTION_TYPES.has(action.type)) {
|
|
5078
|
+
this.executeShopAction(action, selfEl);
|
|
5079
|
+
continue;
|
|
5080
|
+
}
|
|
5074
5081
|
// Tier-B server actions (A2). ALWAYS a simulation here: the canvas is the ADMIN's
|
|
5075
5082
|
// browser and a server action is a public-site write (an email, a webhook, a content
|
|
5076
5083
|
// row) — the toast says what the LIVE site would do.
|
|
@@ -5120,6 +5127,17 @@ class InteractionEngineService {
|
|
|
5120
5127
|
});
|
|
5121
5128
|
this.contextStore.set(effect.slot, value);
|
|
5122
5129
|
}
|
|
5130
|
+
executeShopAction(action, selfEl) {
|
|
5131
|
+
if (action.type === ShopActionType.AddToCart && selfEl)
|
|
5132
|
+
void runShopAction(selfEl, action.type);
|
|
5133
|
+
const detail = { type: action.type, params: action.params ?? {}, target: action.target };
|
|
5134
|
+
window.dispatchEvent(new CustomEvent('iox-action-simulated', { detail }));
|
|
5135
|
+
}
|
|
5136
|
+
/** The product a shop part on the canvas belongs to: its row's, else the route item's, else the page's first —
|
|
5137
|
+
* else the sample (board 10's vase), so an unbound part is still designable. */
|
|
5138
|
+
productFor(el) {
|
|
5139
|
+
return productInScope(this.rowItemFor(el), this.contextData) ?? SAMPLE_PRODUCT;
|
|
5140
|
+
}
|
|
5123
5141
|
/** The repeater item this element belongs to — the nearest marked row ancestor. */
|
|
5124
5142
|
rowItemFor(el) {
|
|
5125
5143
|
const row = el?.closest?.('[data-iox-row-idx]');
|
|
@@ -6717,6 +6735,13 @@ var CompositePresetId;
|
|
|
6717
6735
|
CompositePresetId["Marquee"] = "marquee";
|
|
6718
6736
|
CompositePresetId["Counter"] = "counter";
|
|
6719
6737
|
CompositePresetId["ReadingBar"] = "reading-bar";
|
|
6738
|
+
CompositePresetId["Price"] = "shop-price";
|
|
6739
|
+
CompositePresetId["Variants"] = "shop-variants";
|
|
6740
|
+
CompositePresetId["Quantity"] = "shop-quantity";
|
|
6741
|
+
CompositePresetId["AddToCart"] = "shop-add";
|
|
6742
|
+
CompositePresetId["BuyNow"] = "shop-buy-now";
|
|
6743
|
+
CompositePresetId["CartButton"] = "shop-cart-button";
|
|
6744
|
+
CompositePresetId["CartDrawer"] = "shop-cart-drawer";
|
|
6720
6745
|
})(CompositePresetId || (CompositePresetId = {}));
|
|
6721
6746
|
/** Where a composite sits in the Components panel (composite plan §6d): content blocks, or the interactive
|
|
6722
6747
|
* composites (the Accordion — CC2, the Disclosure — CC2.1, Tabs — CC4a, the Segmented control — CC4b; the floating
|
|
@@ -6725,6 +6750,8 @@ var CompositePaletteGroup;
|
|
|
6725
6750
|
(function (CompositePaletteGroup) {
|
|
6726
6751
|
CompositePaletteGroup["ContentBlocks"] = "content-blocks";
|
|
6727
6752
|
CompositePaletteGroup["Interactive"] = "interactive";
|
|
6753
|
+
/** Commerce E1c (C-D16, commerce board 10): the parts a product page and the bag are built from. */
|
|
6754
|
+
CompositePaletteGroup["Shop"] = "shop";
|
|
6728
6755
|
})(CompositePaletteGroup || (CompositePaletteGroup = {}));
|
|
6729
6756
|
const COMPOSITE_PRESETS = Object.freeze([
|
|
6730
6757
|
{
|
|
@@ -6788,6 +6815,42 @@ const COMPOSITE_PRESETS = Object.freeze([
|
|
|
6788
6815
|
description: 'A thin bar that fills as the page is read — or its section: change it in Interactions.',
|
|
6789
6816
|
build: create => buildReadingBarRecipe(create),
|
|
6790
6817
|
},
|
|
6818
|
+
// Commerce E1c — the shop parts (commerce board 10). Each fills from the product in scope and the bag at runtime.
|
|
6819
|
+
{
|
|
6820
|
+
id: CompositePresetId.Price, group: CompositePaletteGroup.Shop, name: 'Price', icon: 'ph-thin ph-coins',
|
|
6821
|
+
description: 'The chosen option\'s price in your studio\'s currency, and its earlier price struck through when there is one.',
|
|
6822
|
+
build: create => SHOP_RECIPES[ShopRecipe.Price](create),
|
|
6823
|
+
},
|
|
6824
|
+
{
|
|
6825
|
+
id: CompositePresetId.Variants, group: CompositePaletteGroup.Shop, name: 'Options', icon: 'ph-thin ph-swatches',
|
|
6826
|
+
description: 'One row per option — colours as swatches, a few words as chips, a long list as a menu. A sold-out option stays visible and says so.',
|
|
6827
|
+
build: create => SHOP_RECIPES[ShopRecipe.Variants](create),
|
|
6828
|
+
},
|
|
6829
|
+
{
|
|
6830
|
+
id: CompositePresetId.Quantity, group: CompositePaletteGroup.Shop, name: 'Quantity', icon: 'ph-thin ph-plus-minus',
|
|
6831
|
+
description: 'How many to add — never below one, never above what is in stock.',
|
|
6832
|
+
build: create => SHOP_RECIPES[ShopRecipe.Quantity](create),
|
|
6833
|
+
},
|
|
6834
|
+
{
|
|
6835
|
+
id: CompositePresetId.AddToCart, group: CompositePaletteGroup.Shop, name: 'Add to cart', icon: 'ph-thin ph-shopping-cart-simple',
|
|
6836
|
+
description: 'Adds the chosen option and quantity to the bag, reads "Added ✓" for a moment and opens the bag. On the canvas it adds a sample.',
|
|
6837
|
+
build: create => SHOP_RECIPES[ShopRecipe.Add](create),
|
|
6838
|
+
},
|
|
6839
|
+
{
|
|
6840
|
+
id: CompositePresetId.BuyNow, group: CompositePaletteGroup.Shop, name: 'Buy now', icon: 'ph-thin ph-lightning',
|
|
6841
|
+
description: 'Straight to checkout with the chosen option. Does nothing on the canvas.',
|
|
6842
|
+
build: create => SHOP_RECIPES[ShopRecipe.BuyNow](create),
|
|
6843
|
+
},
|
|
6844
|
+
{
|
|
6845
|
+
id: CompositePresetId.CartButton, group: CompositePaletteGroup.Shop, name: 'Cart button', icon: 'ph-thin ph-handbag',
|
|
6846
|
+
description: 'The bag with its live count — put it in your header. It opens the cart drawer.',
|
|
6847
|
+
build: create => SHOP_RECIPES[ShopRecipe.CartButton](create),
|
|
6848
|
+
},
|
|
6849
|
+
{
|
|
6850
|
+
id: CompositePresetId.CartDrawer, group: CompositePaletteGroup.Shop, name: 'Cart drawer', icon: 'ph-thin ph-tote',
|
|
6851
|
+
description: 'The bag: its lines, the subtotal with VAT included, Check out and Keep shopping. Slides in from the edge; a sheet on a phone.',
|
|
6852
|
+
build: create => SHOP_RECIPES[ShopRecipe.CartDrawer](create),
|
|
6853
|
+
},
|
|
6791
6854
|
]);
|
|
6792
6855
|
/**
|
|
6793
6856
|
* The builder's node factory for composite-core recipes: a NEW node as the palette creates one
|
|
@@ -9912,11 +9975,17 @@ class BuilderComponent {
|
|
|
9912
9975
|
const slotValues = this.contextStore.values();
|
|
9913
9976
|
if (!Object.keys(slotValues).length)
|
|
9914
9977
|
return;
|
|
9915
|
-
|
|
9978
|
+
// The globals too: a header's cart button reads `$cart.count` (commerce E1c).
|
|
9979
|
+
const nodes = [...(this.layout ?? []), ...(this.globalElements ?? [])];
|
|
9980
|
+
const slotKeys = collectContextSlotKeys(nodes);
|
|
9916
9981
|
if (!slotKeys.size)
|
|
9917
9982
|
return;
|
|
9918
|
-
this.applyContextBindings(
|
|
9983
|
+
this.applyContextBindings(nodes, withContextSlots({}, slotValues), slotKeys);
|
|
9919
9984
|
}, ...(ngDevMode ? [{ debugName: "contextEffect" }] : []));
|
|
9985
|
+
/** Commerce E1c: the shop parts run on the canvas — the live site's runtime over an in-memory SAMPLE bag that starts
|
|
9986
|
+
* with one line (so the drawer has a line to design) and is never written anywhere. */
|
|
9987
|
+
this.canvasShop = null;
|
|
9988
|
+
this.instanceRegistry = inject(ComponentInstanceRegistryService);
|
|
9920
9989
|
this.layout = [];
|
|
9921
9990
|
this.dataSources = [];
|
|
9922
9991
|
this.orgId = 'default';
|
|
@@ -10113,6 +10182,7 @@ class BuilderComponent {
|
|
|
10113
10182
|
this.autoFitViewport();
|
|
10114
10183
|
this.overlayService.setContainer(this.previewCanvas?.nativeElement || null);
|
|
10115
10184
|
this.attachCanvasFloating();
|
|
10185
|
+
this.attachCanvasShop();
|
|
10116
10186
|
// Builder dispatches synthetic 'scroll' events on .preview-lenis-content from
|
|
10117
10187
|
// the Lenis callback — point the overlay scroll listener at that element.
|
|
10118
10188
|
// (Not previewScrollRef which is the Lenis eventsTarget — dispatching there
|
|
@@ -10237,6 +10307,44 @@ class BuilderComponent {
|
|
|
10237
10307
|
this.canvasTooltips = attachTooltips(root, { topLayer: false, container: canvasFloatingContainer });
|
|
10238
10308
|
this.floatingSub = this.canvasDesignState.state$.subscribe(state => this.applyFloatingDesign(state.tooltips, state.toast));
|
|
10239
10309
|
}
|
|
10310
|
+
attachCanvasShop() {
|
|
10311
|
+
const root = this.previewCanvas?.nativeElement;
|
|
10312
|
+
if (!root || this.canvasShop)
|
|
10313
|
+
return;
|
|
10314
|
+
const transport = simulatedCartTransport(storefrontCatalog(SAMPLE_PRODUCT), SAMPLE_STUDIO, { lines: [SAMPLE_CART_LINE] });
|
|
10315
|
+
this.canvasShop = attachShop(root, {
|
|
10316
|
+
transport,
|
|
10317
|
+
observe: true,
|
|
10318
|
+
productFor: el => {
|
|
10319
|
+
const product = this.interactionEngine.productFor(el);
|
|
10320
|
+
transport.addEntries(storefrontCatalog(product));
|
|
10321
|
+
return product;
|
|
10322
|
+
},
|
|
10323
|
+
publish: (slot, value) => this.contextStore.set(slot, value),
|
|
10324
|
+
swatches: product => (product === SAMPLE_PRODUCT ? SAMPLE_SWATCHES : null),
|
|
10325
|
+
openDrawer: () => {
|
|
10326
|
+
const drawer = this.findByRole([...(this.layout ?? []), ...(this.globalElements ?? [])], ShopRole.CartDrawer);
|
|
10327
|
+
if (drawer?.id)
|
|
10328
|
+
this.instanceRegistry.get(drawer.id)?.open?.();
|
|
10329
|
+
},
|
|
10330
|
+
goToCheckout: () => window.dispatchEvent(new CustomEvent('iox-action-simulated', { detail: { type: 'startCheckout', params: {}, target: '' } })),
|
|
10331
|
+
onCloneClick: part => {
|
|
10332
|
+
const entry = this.overlayService.findNodeByElement(part);
|
|
10333
|
+
if (entry)
|
|
10334
|
+
this.handleClick({ element: entry.ref.element, node: entry.node, componentRef: entry.ref.componentRef });
|
|
10335
|
+
},
|
|
10336
|
+
});
|
|
10337
|
+
}
|
|
10338
|
+
findByRole(nodes, role) {
|
|
10339
|
+
for (const node of nodes ?? []) {
|
|
10340
|
+
if (node.role === role)
|
|
10341
|
+
return node;
|
|
10342
|
+
const below = this.findByRole(node.children ?? [], role);
|
|
10343
|
+
if (below)
|
|
10344
|
+
return below;
|
|
10345
|
+
}
|
|
10346
|
+
return null;
|
|
10347
|
+
}
|
|
10240
10348
|
applyFloatingDesign(tooltips, toast) {
|
|
10241
10349
|
const root = this.previewCanvas?.nativeElement;
|
|
10242
10350
|
const runtime = this.canvasTooltips;
|
|
@@ -10281,6 +10389,8 @@ class BuilderComponent {
|
|
|
10281
10389
|
return null;
|
|
10282
10390
|
}
|
|
10283
10391
|
ngOnDestroy() {
|
|
10392
|
+
this.canvasShop?.destroy();
|
|
10393
|
+
this.canvasShop = null;
|
|
10284
10394
|
this.floatingSub?.unsubscribe();
|
|
10285
10395
|
this.canvasTooltips?.destroy();
|
|
10286
10396
|
this.canvasTooltips = null;
|
|
@@ -14449,12 +14559,13 @@ function button(styleId, label, createConfig, styles = {}) {
|
|
|
14449
14559
|
return withChildren(btn, [text(label, createConfig, BUTTON_LABEL_STYLE)]);
|
|
14450
14560
|
}
|
|
14451
14561
|
/** A Container sized by its content: the palette Container's 200px drop-zone min-height is canvas
|
|
14452
|
-
* furniture, and a specimen has no drop zone. */
|
|
14562
|
+
* furniture, and a specimen has no drop zone. A style that owns its min-height (the quantity stepper) keeps it. */
|
|
14453
14563
|
function box(createConfig, styleId) {
|
|
14454
14564
|
const node = createConfig('Container');
|
|
14455
14565
|
if (styleId)
|
|
14456
14566
|
wearing(node, styleId);
|
|
14457
|
-
|
|
14567
|
+
const ownsMinHeight = !!styleId && elementStyleById(styleId)?.base['minHeight'] !== undefined;
|
|
14568
|
+
return ownsMinHeight ? node ?? null : styled(node, { minHeight: '0' });
|
|
14458
14569
|
}
|
|
14459
14570
|
function boxed(styleId, createConfig, children, styles) {
|
|
14460
14571
|
return withChildren(styled(box(createConfig, styleId), styles), children);
|